🍏 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'
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 constructor
(object
为实例对象,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
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
。
# 两者的区别
- 相同点:
typeof
和instanceof
都用于判断数据的类型。 - 不同点:
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]"
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');
}
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返回
2
3
4
5
6
7
8