Hello, everyone, I am Lin Yiyi, this is the previous easy-to-understand JS detection principle and simulation of the implementation of the article. Read on 😋😋
Mind mapping
Types in JS
- Basic types,
Number, string, null, undefined, Boolean
, new in ES6symbol
In the es11bigint
There are seven basic types - Reference type:
Object, the function
.
Data type detection method
Data types of the detection method of the communist party of China have four typeof, instanceof, constructor, the Object. The prototype. ToString. Call ()
First, the typeof
Typeof detection principle is: at the bottom of the computer according to the BINARY value of JS data type for detection.
typeof
The return value after detecting the type is onestring
ES5 also throws a string for an undefined variable typeundefined
Instead of reporting an error. But the use oflet, const
Declared variables can also cause temporary dead zones to be thrownReferenceError
.
typeof undefined //"undefined"
typeof a // "undefined"
typeof b // "ReferenceError"
let b
typeof 12 //"number"
typeof NaN //"number"
typeof ' ' //"string"
typeof 1n //"bigint"
typeof function(){} //"function"
Copy the code
- (disadvantages)
typeof
Can detect in addition tonull
Data types other than type.null
By testing intoobject
This is a bug left over from history. - (disadvantages)
typeof
Can’t detect specificobject
Type, because the binary of object types starts with 000. Such astypeof [] //"object"
Detect arrays, re’s, dates, etc. - Other types of binary,
000
Object,00000...
Null,1
An integer,010
Floating point number,100
String,110
Boolean value,- 2 ^ 30
undefined
Why is typeof NULL detectedobject
The binary value of null is 000, whereas the binary value of object starts with 000. Therefore, the typeof null is also detected as object. This is a historical bug
Consider: why can typeof judge function judge isfunction
Type instead ofobject
A typeOf judgment function calls the call method to determine whether a function is an object. C. function D. function
You can be there just to make up the instanceof number
Instanceof checks whether the type on the right appears in the prototype chain of the instance on the left, and returns true or false.
instanceof
To determine which constructor the instance belongs toinstanceof
Determine that the result returned is a Boolean value.instanceof
Is used to check whether the current instance belongs to a class. Can be used to solvetypeof
A problem with a specific object type cannot be detected.
let ary = []
console.log(ary instanceof Array) // true
let reg = / ^ /
console.log(reg instanceof RegExp) // true
Copy the code
- (Disadvantage) as long as the current class appears on the prototype chain of the instance
true
, thenObject
The result of type checking is alwaystrue
If the prototype of the instance has been modified, even if the result of the detection istrue
It is also inaccurate. - (disadvantages)
instanceof
Cannot detect base data types.
// All types that appear on the prototype chain are judged to be true
let ary = []
console.log(ary instanceof Object) // true
function fn(){}
fn.prototype = Array.prototype // The prototype has been modified
let f = new fn()
console.log(f instanceof Array) // true
console.log(f instanceof Function) // false
// Cannot detect basic array types
console.log(1 instanceof Number) //false
console.log(' ' instanceof String) //false
console.log(false instanceof Boolean) //false
Copy the code
Warm up the topic
-
- Determine the results
console.log( Function instanceof Object ); // true
console.log( Object instanceof Function ); // true
Copy the code
Object is going to be a function here
-
- Determine the results
function f(){ return; }
console.log(new f() instanceof f); // true
Copy the code
There is no doubt that the result here is true, because the prototype chain of the left instance is an instance of the right constructor
function f(){ return f; }
console.log(new f() instanceof f); // fale
Copy the code
Function f(){return f; function f(){return f; }) instanceof function f(){ return f; } result is false
Think and simulate instanceof implementation
The result is judged by whether the type on the right appears in the prototype chain of the left instance. __proto__ === class.prototype: true; otherwise, false. For prototype and prototype chain unfamiliar can see interview | you have to know JS prototype and prototype chain.
function _instanceof(example, classP) {
let proto = Object.getPrototypeOf(example),
classPrototype = classP.prototype
while (true) {
if (proto === classPrototype) {
return true
}
if (proto === null) {
return false
}
proto = Object.getPrototypeOf(proto)
}
_instanceof([], Array) //true
_instanceof(' '.Array) // false
_instanceof(' '.Object) // true
Copy the code
There can be no constructor there
The constructor detection mechanism is as follows: constructor stores the constructor itself and uses the stored constructor to detect the type. Not familiar with the constructor can also see the interview | you have to know the JS prototype and prototype chain.
constructor
You can detect basic types, which is a little bit moreinstanceof
Be useful
let ary = []
ary.constructor === Array / / true, ary. Constructor = = > Array. The prototype. The constructor
ary.constructor === String // false
ary.constructor === Object // false
let a = 1
a.constructor === Number // true
let s = ' '
s.constructor === String // true
Copy the code
- (disadvantages)
constructor
和instanceof
It has the same flaw, which isconstructor
It can be modified which is a redirect
Number.prototype.constructor = 'abc'
let a = 1
a.constructor === Number // false
Copy the code
Four, the Object. The prototype. ToString. Call (), type of measurement standard
Detection mechanism is: using the Object. The prototype. ToString returns the instance owning class information, by changing the toString this point to return the type of the specified argument.
Object.prototype.toString
The return format is fixed to'[object xxx]'
, can detect any type
Object.prototype.toString.call(1) //"[object Number]"
Object.prototype.toString.call(' ') //"[object String]"
Object.prototype.toString.call(null) //"[object Null]"
Object.prototype.toString.call(undefined) //"[object Undefined]"
Object.prototype.toString.call(Symbol()) //"[object Symbol]"
Object.prototype.toString.call([]) //"[object Array]"
Object.prototype.toString.call(function(){}) //"[object Function]"
Object.prototype.toString.call({}) //"[object Object]"
Copy the code
- You can’t extract the data type directly, you need to transform it to get the direct type
Five, package a universal detection methodtoType()
1. Type detection in jQuery
(function () {
// toType in jquery
let class2type = {},
toString = class2type.toString
// Set the type mapping table
let arrType = ['Number'.'String'.'Boolean'.'Symbol'.'Array'.'Date'.'Error'.'RegExp'.'Function'.'Object']
arrType.forEach(item= > {
class2type[`[object ${item}] `] = item.toLowerCase()
});
function toType(checkType) {
if (checkType === null || checkType == undefined) {
return checkType + ' '
}
return typeof checkType == 'object' || typeof checkType == 'function' ? class2type[toString.call(checkType)] : typeof checkType
}
window.toType = toType
})()
toType(1) //"number"
toType(' ') //"string"
toType(null) //"null"
toType(undefined) //"undefined"
toType({}) //"object"
toType(function(){}) //"function"
toType([]) //"array"
Copy the code
Nature or use of the Object. The prototype. ToString. Call ()
2. Self-encapsulate a simpler selfType()
(function () {
function selfType(checkType) {
let res = {}.toString.call(checkType).split(' ') [1].split('] ') [0].toLowerCase() // Regex can be used
return res
}
window.selfType = selfType
})()
selfType(' ') //"string"
selfType(1) //"number"
selfType(null) //"null"
selfType(undefined) //"undefined"
selfType(function(){}) //"function"
selfType({}) //"object"
Copy the code
Sixth, the end
Thanks for reading so far, I’m Lin Yiyi, see you next time. If this article is of any help or inspiration to you, please give it a thumbs upgithub star