A variable can hold two types of values: Primitive values and reference values.
ES6 introduces a new primitive data type, Symbol, that represents unique values. It is the seventh data type in JavaScript, with Undefined, Null, Boolean, String, Number, and Object being the first six.
Basic types of
There are six basic data types in JavaScript: Undefined, Null, Boolean, Number, String, Symbol (new in ES 6)!
Convention: primitive data type and primitive data type.
Values of basic data types are accessed by value.
-
Values of primitive types are immutable
var str = "123hello321"; str.toUpperCase(); // 123HELLO321 console.log(str); // 123hello321 Copy the code
-
A comparison of primitive types is a comparison of their values
var a = 1; var b = true; console.log(a == b); // true console.log(a === b); // false Copy the code
The data types of A and B above are different, but it is also possible to compare values because an implicit conversion of the data types is automatically performed before the comparison.
= =
: Compares values only= = =
: Not only value comparison, but also data type comparison
-
Variables of basic types are stored in the Stack
var a,b; a = "zyj"; b = a; console.log(a); // zyj console.log(b); // zyj a = "Ha ha"; // Change the value of a does not affect the value of b console.log(a); / / ha ha console.log(b); // zyj Copy the code
The stack memory contains the identifier of the variable and its value
Reference types
Apart from the six basic data types mentioned above, all that remains are reference types, collectively known as Object types. Subdivided, there are: Object, Array, Date, RegExp, Function, and so on.
Values of reference types are accessed by reference.
-
The value of a reference type is mutable
var obj = {name:"zyj"}; // Create an object obj.name = "percy"; // Change the name attribute obj.age = 21; // Add the age attribute obj.giveMeAll = function(){ return this.name + ":" + this.age; }; // Add the giveMeAll method obj.giveMeAll(); Copy the code
-
A comparison of reference types is a comparison of references
var obj1 = {}; // Create an empty object, obj1 var obj2 = {}; // Create an empty object obj2 console.log(obj1 == obj2); // false console.log(obj1 === obj2); // false Copy the code
Since obj1 and obj2 refer to two different objects stored in the heap, the values of obj1 and obj2 are different!
-
The value of the reference type is an Object stored in the Heap.
Unlike other programming languages, JavaScript cannot directly manipulate the memory space of an object (heap memory).
var a = {name:"percy"}; var b; b = a; a.name = "zyj"; console.log(b.name); // zyj b.age = 22; console.log(a.age); / / 22 var c = { name: "zyj".age: 22 }; Copy the code
The diagram is as follows:
-
Stack memory holds the variable identifier and a pointer to the object in heap memory
-
The heap memory holds the contents of the object
-
Detection of type
-
Typeof: Usually detects the base type.
1. For basic types, all but null returns the correct result. 2. For reference types, return object except function. 3. For null, return object.
4. Return function type for function.
var a;
typeof a; // undefined
a = null;
typeof a; // object
a = true;
typeof a; // boolean
a = Awesome!;
typeof a; // number
a = "hello";
typeof a; // string
a = Symbol(a);typeof a; // symbol
a = function(){}
typeof a; // function
a = [];
typeof a; // object
a = {};
typeof a; // object
a = /aaa/g;
typeof a; // object
Copy the code
-
Instanceof: usually checks the reference type to determine whether A is an instanceof B
({}) instanceof Object // true ([]) instanceof Array // true (/aa/g) instanceof RegExp // true (function(){}) instanceof Function // true Copy the code
-
Object. The prototype. ToString: usually detection basic types and reference types. You can identify exactly which built-in type an object value belongs to, more accurately than typeof & Instanceof.
[[Class]] is an internal attribute of any built-in object. The value is a type string that can be used to determine the type of the value.
In JavaScript code, the only way can access this property is through the Object. The prototype. ToString, usually as follows:
Object.prototype.toString.call(value) Copy the code
Object.prototype.toString.call(123) // '[object Number]' Object.prototype.toString.call('123') // '[object String]' Object.prototype.toString.call(null) // '[object Null]' Object.prototype.toString.call(undefined) // '[object Undefined]' Object.prototype.toString.call(Math) // '[object Math]' Object.prototype.toString.call({}) // '[object Object]' Object.prototype.toString.call([]) // '[object Array]' ({}).toString() // [object Object] Copy the code
Type conversion
Because JS is a weakly typed language, type conversions occur very frequently, and most familiar operations begin with type conversions.
Fortunately, most of the conversion rules are actually quite simple, as shown in the following table:
In this case, the more complicated parts are the conversions between Number and String, and between objects and primitive types. Let’s take a look at the rules for each transformation.
1. StringToNumber
String to number conversions, there is a syntax structure, type conversions support decimal, binary, octal, and hexadecimal, for example:
- 30; // Decimal => 30
- 0 b111; // Binary => 7
- 0 o13; // octal => 11
- 0 XFF. // Hexadecimal => 255
- 1e3; // Scientific counting => 1000
- 1 e – 2; // Scientific counting => -0.01
Other types => NaN
2. NumberToString
On a smaller scale, the numeral-to-string conversion is a decimal representation that perfectly conforms to your intuition.
console.log(1e3 + 'ok'); // 1000ok
Copy the code
3. Boxing conversion (basic type => Object)
Each basic type Number, String, Boolean, Symbol have corresponding classes in the object, the so-called boxing conversion, is to convert the basic type into the corresponding object, it is a rather important type conversion.
Attention! The boxing mechanism frequently produces temporary objects, and in some performance-critical scenarios, we should avoid boxing primitives.
For example, the number below does not change and only the numberObj temporary object is generated.
Scenario 1: We can use the call method of a function to force boxing.
var number = 123;
var numberObj = (function(){ return this; }).call(number);
numberObj instanceof Number; // true
number instanceof Number; // false
Copy the code
Scenario 2: Using the built-in Object function, we can explicitly invoke the boxing capability in JavaScript code.
var number = 123;
var numberObj = Object(number);
numberObj instanceof Number; // true
number instanceof Number; // false
Copy the code
4. Unpacking conversion (Object => Basic type)
In the JavaScript standard, ToPrimitive is defined as a function that converts object types ToPrimitive types (i.e., unboxed conversions).
The unboxed conversion attempts to call valueOf and toString to get the unboxed base type. If neither valueOf nor toString exists, or if no primitive type is returned, a TypeError is generated.
var o = {
valueOf : () = > {console.log("valueOf"); return {}},
toString : () = > {console.log("toString"); return {}}
}
o * 2 / o + ' '
// valueOf
// toString
// TypeError
Copy the code
As you can see, a typical operation would execute valueOf first, then toString, and finally raise a TypeError, indicating that the unboxing conversion failed.
The unboxing conversion toString calls toString first. Let’s change this operation from o*2 to String(o), and you’ll see that the order of calls has changed.
String(o)
// toString
// valueOf
// TypeError
Copy the code
After ES6, objects are also allowed to override the original behavior by explicitly specifying the @@Toprimitive Symbol.
var o = {
valueOf : () = > {console.log("valueOf"); return {}},
toString : () = > {console.log("toString"); return {}}
}
o[Symbol.toPrimitive] = () = > {console.log("toPrimitive"); return "hello"}
console.log(o + "")
// toPrimitive
// hello
Copy the code
Question time
-
Why do some programming specifications require void 0 instead of undefined?
Because JavaScript code uses undefined as a variable rather than a keyword, which is one of the most recognized design mistakes of the JavaScript language, we recommend using void 0 to get undefined to avoid inadvertent tampering.
-
Isn’t 0.1 + 0.2 equal to 0.3? Why isn’t that the case in JavaScript?
By floating-point definition, non-integer Number types cannot be compared using == (nor can ===) :
console.log( 0.1 + 0.2= =0.3); // false Copy the code
In fact, what is wrong here is not the conclusion, but the method of comparison, and the correct method of comparison is to use the minimum precision provided by JavaScript:
console.log( Math.abs(0.1 + 0.2 - 0.3) < =Number.EPSILON); // true Copy the code
-
Why do methods added to objects work on primitive types?
The. Operator provides the boxing operation, which constructs a temporary object from the underlying type, allowing us to call the corresponding object’s methods on the underlying type.
Number.prototype.hello = () = > console.log('hello'); (123).hello(); // hello Copy the code
-
Is a variable an array?
var arr = [1.2.3] Array.isArray(arr) arr instanceof Array arr.constructor === Array Object.prototype.toString.call(arr) === '[object Array]' Copy the code
reference
- Geek time – Relearn the front end