"Earnestly JavaScript core principles" : https://kaiwu.lagou.com/course/courseInfo.htm?courseId=601#/contentCopy the code
Data type concept
The above data types can be roughly divided into two categories for storage:
- The base type is stored in stack memory, and when referenced or copied, an identical variable is created;
- Reference types are stored in heap memory and store addresses. Multiple references point to the same address. There is a concept of “sharing” involved.
The following two pieces of code will explain reference types directly to understand the core concept of “sharing”.
let a = {
name: 'lee'.age: 18
}
let b = a;
console.log(a.name); // The first console
b.name = 'son';
console.log(a.name); // The second console
console.log(b.name); // The third console
Copy the code
let a = {
name: 'Julia'.age: 20
}
function change(o) {
o.age = 24;
o = {
name: 'Kath'.age: 30
}
return o;
}
let b = change(a); // Note that there is no new here, there will be a special article on new later
console.log(b.age); // The first console
console.log(a.age); // The second console
Copy the code
If the first return line is removed, what does B return?
Data type detection
The first judgment method:typeof
typeof 1 // 'number'
typeof '1' // 'string'
typeof undefined // 'undefined'
typeof true // 'boolean'
typeof Symbol(a)// 'symbol'
typeof null // 'object'
typeof [] // 'object'
typeof {} // 'object'
typeof console // 'object'
typeof console.log // 'function'
Copy the code
The second judgment method:instanceof
If an object is new, then the new object is the object from which it inherits its prototype chain. Using instanceof, we can determine whether this object is the object generated by the previous constructor, and thus basically determine the data type of this new object
let Car = function() {}
let benz = new Car()
benz instanceof Car // true
let car = new String('Mercedes Benz')
car instanceof String // true
let str = 'Covid-19'
str instanceof String // false
Copy the code
Implement an Instanceof
function myInstanceof(children, parent) {
// Use typeof to determine the underlying data type. If so, return false
if(typeofchildren ! = ='object' || children === null) return false;
// getProtypeOf is an Object API that can get the parameters of the prototype Object
let proto = Object.getPrototypeOf(children);
while(true) { // Loop down until you find the same prototype object
if(proto === null) return false;
if(proto === parent.prototype) return true;// Find the same prototype object, return true
proto = Object.getPrototypeof(proto); }}// verify that myInstanceof is OK
console.log(myInstanceof(new Number(123), Number)); // true
console.log(myInstanceof(123.Number)); // false
Copy the code
differences
- Instanceof can accurately determine complex reference data types, but not the underlying data types.
- Typeof also suffers from the fact that while it can determine the underlying data type (except null), it cannot determine any reference data type other than the function type.
The third judgment method: Object. The prototype. ToString
- ToString () is the prototype method of Object, which can be called in a uniform return format
[object Xxx]
“, where Xxx is the type of the object. For Object objects, a call to toString() returns this[object Object]
Other objects need to be called by call to return the correct type information
Object.prototype.toString({}) // "[object Object]"
Object.prototype.toString.call({}) // Same result as above, add call also ok
Object.prototype.toString.call(1) // "[object Number]"
Object.prototype.toString.call('1') // "[object String]"
Object.prototype.toString.call(true) // "[object Boolean]"
Object.prototype.toString.call(function(){}) // "[object Function]"
Object.prototype.toString.call(null) //"[object Null]"
Object.prototype.toString.call(undefined) //"[object Undefined]"
Object.prototype.toString.call(/123/g) //"[object RegExp]"
Object.prototype.toString.call(new Date()) //"[object Date]"
Object.prototype.toString.call([]) //"[object Array]"
Object.prototype.toString.call(document) //"[object HTMLDocument]"
Object.prototype.toString.call(window) //"[object Window]"
Copy the code
- To achieve a global general data type judgment method
function getType(obj){
let type = typeof obj;
if(type ! = ="object") { // Check typeof first, if it is a basic data type, return directly
return type;
}
// If typeof returns object, regex returns result
return Object.prototype.toString.call(obj).replace(/^\[object (\S+)\]$/.'$1'); // Note that there is a space between the re
}
getType([]) // "Array" typeof [] is object, so toString is returned
getType('123') // "string" typeof returns directly
getType(window) // "Window" toString returns
getType(null) Typeof Null is object and toString is required
getType(undefined) // "undefined" typeof returns directly
getType() // "undefined" typeof returns directly
getType(function(){}) // "function" typeof can determine, so the first letter is lowercase
getType(/123/g) / / "RegExp" toString returns
Copy the code
Data type conversion
'123'= =123 // false or true?
' '= =null // false or true?
' '= =0 // false or true?[] = =0 // false or true?[] = =' ' // false or true?[] = =! []// false or true?
null= =undefined // false or true?
Number(null) // Return what?
Number(' ') // Return what?
parseInt(' '); // Return what?{} +10 // Return what?
let obj = {
[Symbol.toPrimitive]() {
return 200;
},
valueOf() {
return 300;
},
toString() {
return 'Hello'; }}console.log(obj + 200); // What is the printed value here?
Copy the code
Cast casting
- The cast methods include
ParseInt (), parseFloat(), toString(), String(), Boolean()
Cast rules for the Number() method
- If Boolean, true and false are converted to 1 and 0, respectively;
- If it is a number, return itself;
- If null, return 0;
- If undefined, NaN is returned;
- If it is a string, follow these rules: If the string contains only numbers (or a string of hexadecimal digits starting with 0X / 0X, plus or minus signs are allowed), convert it to decimal; If the string contains a valid floating-point format, convert it to a floating-point value; If it is an empty string, it is converted to 0; NaN is returned if it is not a string of the above format;
- If Symbol, an error is thrown;
- Call this method if it is an object and [symbol.toprimitive] is deployed, otherwise call the valueOf() method of the object and convert the returned value according to the previous rules; If the result of the conversion is a NaN, the Object’s toString() method is called, and the conversion returns the corresponding value in the previous order (the Object conversion rules are covered in more detail below).
Number(true); / / 1
Number(false); / / 0
Number('0111'); / / 111
Number(null); / / 0
Number(' '); / / 0
Number('1a'); //NaN
Number(-0X11); / / - 17
Number('0X11') / / 17It can not be converted into numbers, and finally outputNaNThe results of theCopy the code
Boolean() method cast rules
- The rule is: undefined, null, false, ”, 0 (including +0, -0), NaN is converted to false, all other things are true.
Boolean(0) //false
Boolean(null) //false
Boolean(undefined) //false
Boolean(NaN) //false
Boolean(1) //true
Boolean(13) //true
Boolean('12') //true
Copy the code
- ParseInt (), parseFloat(), toString(), String() will be updated later
Implicit type conversion
- By logical operators (&&, | |,!) , operators (+, -, *, /), relational operators (>, <, <=, >=), equality operators (==), or if/while conditions. Implicit type conversions occur when two data types are not identical
Implicit type conversion rule for ‘==’
- If the types are the same, no type conversion is required.
- If one of the operators is null or undefined, the other operator must be null or undefined to return true. Otherwise, false is returned.
- If one of them is of type Symbol, return false;
- If the two operation values are string and number, the string is converted to number.
- If an operation value is Boolean, convert to number;
- If an operation value is object and the other is string, number, or symbol, the object is converted to its original type for evaluation (call the valueOf/toString method of object for conversion).
As follows:
null= =undefined // true rule 2
null= =0 // Rule 2 of false
' '= =null // Rule 2 of false
' '= =0 // True rule 4: String is converted implicitly to Number before comparison
'123'= =123 // True rule 4: String is converted implicitly to Number before comparison
0= =false // True e rule Boolean is implicitly converted to Number before comparison
1= =true // True e rule Boolean is implicitly converted to Number before comparison
var a = {
value: 0.valueOf: function() {
this.value++;
return this.value; }};// Note that a can be equal to 1, 2, 3 again
console.log(a == 1 && a == 2 && a ==3); //true f rule Object implicit conversion
// If a==3 or the number before it is executed, it is false because value has been added
Copy the code
Implicit type conversion rules for ‘+’
- The ‘+’ operator can be used not only for numeric addition, but also for string concatenation. Only if both sides of the ‘+’ sign are numbers, we’re adding; If both sides are strings, concatenation is done without implicit type conversion.
There are also some special rules, as shown below.
- If one of them is a string and the other is undefined, NULL, or Boolean, the toString() method is called to concatenate strings. For pure objects, arrays, regees, and so on, the default conversion method that calls the object has precedence (more on that in the next lecture) before concatenation.
- If one of them is a number and the other is undefined, NULL, Boolean, or a number, it is converted to a number for addition, again referring to the previous rule.
- If one of them is a string and the other is a number, they are concatenated according to string rules.
Again, the code is used to understand the above rules, as shown below.
1 + 2 // 3 General situation
'1' + '2' // '12' normal case
// Let's look at the special case
'1' + undefined // "1undefined" rule 1, undefined conversion string
'1' + null // "1NULL" rule 1, null converts string
'1' + true // "1true" rule 1, true converts strings
'1' + 1n // '11' is a special string that is added to BigInt, which is converted to a string
1 + undefined // NaN rule 2, undefined convert numbers to add NaN
1 + null // 1 rule 2, null is converted to 0
1 + true // 2 Rule 2, true converts to 1, and the two add up to 2
1 + 1n // Error cannot add BigInt and Number directly
'1' + 3 // Rule 3, string concatenation
Copy the code
Object conversion rules
- The rules for converting objects call the built-in [ToPrimitive] function first, and the rule logic is as follows:
- If the Symbol. ToPrimitive method is deployed, call it first and return it.
- Calls valueOf(), which returns if converted to an underlying type;
- Call toString(), which returns if cast to base type;
- If none of the underlying types are returned, an error is reported.
var obj = {
value: 1.valueOf() {
return 2;
},
toString() {
return '3'},Symbol.toPrimitive]() {
return 4}}console.log(obj + 1); / / output 5
// Since Symbol. ToPrimitive is available, execute this first; If Symbol. ToPrimitive is deleted, valueOf prints 3; If valueOf is also removed, the toString call returns '31'(string concatenation)
// Let's look at two special cases:
10 + {}
// "10[object object]" {} will call valueOf by default, which is {}, not the base type. Continue the conversion, call toString, return "[object object]", and then perform '+' with 10, according to the string concatenation rules, refer to rule C of '+'
[1.2.undefined.4.5] + 10
// "1,2, 4,510", note that [1,2,undefined,4,5] will call valueOf by default. The result is still the same array, not the underlying data type. Again, follow the string concatenation rules, refer to rule 3 of '+'
Copy the code
conclusion
- Basic concepts of datatypes: This is a must-know knowledge as a foundation for a deeper understanding of JavaScript.
- Judgment method of data type:
Typeof and instanceof, as well as the Object. The prototype. ToString judgment data types, handwritten instanceof code snippet
- Data type conversion mode: Two data types of conversion mode, daily code writing process should pay more attention to implicit conversion, if the understanding is not in place, it is easy to cause bugs in the coding process, get some unexpected results.