JS data type determination typeof principle instanceof principle

Posted by salomo on Tue, 02 Nov 2021 02:42:34 +0100

typeof

Typeof is generally used to judge the type of a variable. We can use typeof to judge the seven types of number, string, object, Boolean, function, undefined and symbol. This judgment can help us solve some problems; However, it's a pity that when typeof judges the data of an object, it can only tell us that the data is an object, not the specific object.

principle

In fact, when js stores a variable at the bottom, it will store its type information in the lower 1-3 bits of the variable's machine code 👉

  • 000: object
  • 010: floating point number
  • 100: String
  • 110: Boolean
  • 1: Integer

but, for undefined and null, the information storage of these two values is a little special.

null: all machine codes are 0

undefined: expressed as an integer of − 2 ^ 30

Therefore, there is a problem when typeof judges null. Since all machine codes of null are 0, it is directly treated as an object.

Therefore, when using typeof to judge the type of variable, we should note that it is best to use typeof to judge the basic data type (including symbol) to avoid the judgment of null.

defect

  • Cannot distinguish between object and null. The value of typeof null is object
typeof null // object
  • It is impossible to determine which object type it is
typeof new Array() // object
typeof new String('123') // object
typeof new Number(1) // object

instanceof

instanceof is mainly used to judge whether an instance belongs to a certain type, or whether an instance is an instance of its parent type or ancestor type.

principle

In fact, the main implementation principle of instanceof is that as long as the prototype of the variable on the right is on the prototype chain of the variable on the left. Therefore, instanceof will traverse the prototype chain of the left variable during the search until the prototype of the right variable is found. If the search fails, false will be returned to tell us that the left variable is not an instance of the right variable.

function new_instance_of(leftVaule, rightVaule) { 
    let rightProto = rightVaule.prototype; // Take the prototype value of the right expression
    leftVaule = leftVaule.__proto__; // Take the left expression__ proto__ value
    while (true) {
    	if (leftVaule === null) {
            return false;	
        }
        if (leftVaule === rightProto) {
            return true;	
        } 
        leftVaule = leftVaule.__proto__ 
    }
}

defect

  • Cannot determine null, undefined
  • The data type of literal data cannot be determined
1 instanceof Number // false
'missy' instanceof String // false

Object.prototype.toString.call

We can use this method to accurately judge the type of a variable

Object.prototype.toString.call({})              // '[object Object]'
Object.prototype.toString.call([])              // '[object Array]'
Object.prototype.toString.call(() => {})        // '[object Function]'
Object.prototype.toString.call('seymoe')        // '[object String]'
Object.prototype.toString.call(1)               // '[object Number]'
Object.prototype.toString.call(true)            // '[object Boolean]'
Object.prototype.toString.call(Symbol())        // '[object Symbol]'
Object.prototype.toString.call(null)            // '[object Null]'
Object.prototype.toString.call(undefined)       // '[object Undefined]'

Object.prototype.toString.call(new Date())      // '[object Date]'
Object.prototype.toString.call(Math)            // '[object Math]'
Object.prototype.toString.call(new Set())       // '[object Set]'
Object.prototype.toString.call(new WeakSet())   // '[object WeakSet]'
Object.prototype.toString.call(new Map())       // '[object Map]'
Object.prototype.toString.call(new WeakMap())   // '[object WeakMap]'```

summary

In short, it is ok for us to use typeof to judge the basic data type, but we should pay attention to the problem when using typeof to judge the null type. If you want to judge the specific type of an Object, you can consider using instanceof, but instanceof may also be inaccurate. For example, an array can be judged as an Object by instanceof. Therefore, we can use the Object.prototype.toString.call method to accurately judge the type of Object instance.

Reference articles
On the implementation principle of instanceof and typeof

Topics: Javascript