1. 前言
之前对于 typeof
和 instanceof
用法的印象仅停留在可以使用它们对变量的类型进行检测,但是具体的差别并不很熟悉,如果你和我有同样的困惑,那接着往下看吧!
2. 区别
从官方文档中,可以了解到两者的定义分别如下:
typeof
:返回一个字符串,表示一个未经计算的操作数的类型instanceof
:检测构造函数的prototype
是否存在某个实例对象的原型链上
能让你直观地感受到有时候 typeof
检测并不准确的例子如下:
当你想判断一个变量是否为数组时,typeof 只能检测为 object,而 instanceof 能告诉你是否为数组。
let arr = []
typeof arr // object
arr instanceof Array // true
1)typeof
- 能判断 “值类型”
- 能判断 “函数”
- 能判断是否为 “引用类型”,但只能知道其为 object,无法辨别是否为数组、null或者对象
举一个不太恰当的例子,typeof
相当于用于辨别一个人的性别,但是它没办法知道这个人的生平或其他特质。
console.log(typeof 'str'); // string
console.log(typeof 10); // number
console.log(typeof {}); // object
console.log(typeof []); // object
console.log(typeof function(){}); // function
2)instanceof
而 instanceof
与 typeof
不同的是,它可以判断你与某个人是否存在联系,你身上的血液是否流淌着这个人遗传给你的某些DNA。
就犹如下面的代码中,a 是 A 的实例,在 A 的原型链上挂载了某些特质
(text)后,实例a 也同时拥有了该特质,并且通过 instanceof
检测的时候,可以发现是正确的,因此我们称:构造函数A的原型链,是存在实例对象a 的原型链上的。而 typeof
是无法做到这一点的。
注:
关于原型链,后续会单独出一篇文章来讲。
// 声明构造器
function A(){}
// 创建实例
let a = new A()
// 往构造器上挂载一个 text 属性
A.prototype.text = 'prototype text'
console.log(a);
// 打印结果如下
A {
__proto__:
text: prototype text
}
console.log(a instanceof A) // true
3. 用法
1)typeof
以下两种写法都可以
typeof xxx
typeof(xxx)
返回值是 字符串
,如 "object"
,因此若有题目如下,解答如下
let a = {}
typeof(typeof a) // string
2)instanceof
写法如下
object instanceof constructor
// 示例
function A(){}
var a = new A()
a instanceof A // true
a instanceof Object // true
值得注意的是,第一个函数必须是 实例对象
,第二个函数必须是 构造函数
这句话的意思,可以分别看下面两段代码:
// 第一个函数必须是实例对象
var str = 'str'
var str1 = new String()
str instanceof String // false, str 非对象实例
str1 instanceof String // true, str1 是 String 的实例
// 第二个函数必须是构造函数
function A(){}
let a = new A()
let b = new A()
console.log(a instanceof b);
// TypeError: Right-hand side of 'instanceof' is not callable, 也就是 instanceof 右边不能是实例对象
3)需注意的点
var str = 'str'
str instanceof String // false
var str1 = new String()
str1 instanceof String // true
var obj = {} // 对象不需要定义原型
obj instanceof Object // true
var obj1 = Object.create(null); // Object.create: 一种创建非 Object 实例的对象的方法
obj1 instanceof Object // false