目录

🍏 JavaScript typeof 与 instanceof

# 概念

# typeof

  • 返回一个字符串,表示未经计算的操作数的类型

  • 使用语法: typeof operand / typeof (operand)operand 为对象或者原始值的表达式)

🌰 例子:

typeof 1 // 'number'
typeof '1' // 'string'
typeof undefined // 'undefined'
typeof true // 'boolean'
typeof Symbol() // 'symbol'
typeof null // 'object'
typeof [] // 'object'
typeof {} // 'object'
typeof console // 'object'
typeof console.log // 'function'
1
2
3
4
5
6
7
8
9
10
  • typeof null 是一个特殊情况, null 本身不是对象。所以 typeof 不能判断 null 的情况。判断变量是否为空,可以直接在 if 语句中判断是否 ===null 即可。

  • 对于引用数据类型,可以使用 typeof 判断,除了 函数 function 可以被识别出来类型,其他的都是 object 类型。

  • 判断一个变量是否存在,可以使用 typeof :如 typeof a != 'undefined' 。如果直接 if(a) ,当变量为空时会报错。

# instanceof

  • instanceof 运算符用于检测 构造函数的 prototype 属性是否出现在某个实例对象的原型链上。

    理解为,因为构造函数可以通过 new 生成实例对象, instance 判断某个实例对象是否为某个构造函数的实例对象。

  • 使用语法: object instanceof constructorobject 为实例对象, constructor 为构造对象)。

🌰 例子:

let Car = function() {}
let benz = new Car()
benz instanceof Car // true

let car = new String('xxx')
car instanceof String // true
let str = 'xxx'
str instanceof String // false
1
2
3
4
5
6
7
8

instanceof 的实现原理:

fucntion iInstanceof(left, right) {
  // 如果左边不为对象类型或者为空,则返回 false
  if(typeof left !== 'object' || left === null) return false;
  
  let proto = Object.getPrototypeOf(left);
  while(true) {
    if(proto === null) return false;
    if(proto === right.prototype) return true;
   	proto = Object.getPrototype(proto)
  }
  
}
1
2
3
4
5
6
7
8
9
10
11
12

顺着原型链去找,直到找到相同的原型对象,如果找到则返回 true ,找不到则返回 false

# 两者的区别

  • 相同点: typeofinstanceof 都用于判断数据的类型。
  • 不同点:
    • typeof 会返回一个变量的基本类型的字符串; instanceof 返回的是一个布尔值;
    • instanceof 可以准确判断 复杂引用数据类型,但是不能准确判断基础数据类型; typeof 虽然可以 准确判断基础数据类型,但是引用数据类型中,除了 function 以外,其他的数据类型无法判断。

可以看到,两种方法判断数据类型都有弊端,并不能满足所有的场景的需求。如果需要通用监测数据类型可以采用 Object.prototype.toString 方法,统一返回 [object XXX] 格式。

🌰 例子:

Object.prototype.toString({}) // "[object Object]"
Object.prototype.toString.call({}) // 结果桶上升
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]"

1
2
3
4
5
6
7
8
9
10
11
12
13
14

可以将这个方法封装为一个全局通用的数据类型判断方法:

function getType(obj) {
  let type = typeof obj
  if (type !=== 'ojbect') {
    return type
  }
  return Object.prototype.toString.call(obj).replace(/^\[object (\S+)\]$/, '$1');
}
1
2
3
4
5
6
7

使用如下:

getType([])     // "Array" typeof []是object,因此toString返回
getType('123')  // "string" typeof 直接返回
getType(window) // "Window" toString返回
getType(null)   // "Null"首字母大写,typeof null是object,需toString来判断
getType(undefined)   // "undefined" typeof 直接返回
getType()            // "undefined" typeof 直接返回
getType(function(){}) // "function" typeof能判断,因此首字母小写
getType(/123/g)      //"RegExp" toString返回
1
2
3
4
5
6
7
8

# 参考

📢 上次更新: 2022/09/02, 10:18:16