instanceof定义: instanceof运算符用于检测构造函数的prototype属性是否出现在实例对象的原型链上。
示例代码:
function Car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
const auto = new Car('Honda', 'Accord', 1998);
console.log(auto instanceof Car);
// expected output: true
console.log(auto instanceof Object);
// expected output: true
因为auto.__proto__ === Car.prototype
,也就是构造函数Car的prototype属性在auto的原型链上,所以auto instanceof Car
为true,又因为auto.__proto__.proto__ === Object.prototype
,同样是因为Object的prototype属性在auto的原型链上,所以auto instanceof Object
为true。
一切到目前为止都很正常,本着求知(zhaocha)的心态,我试了下下面的几个语句:
let obj = {}
obj instanceof Object // true
let num = 1
num instanceof Number // false
num instanceof Object // false
let str = 'str'
str instanceof String // false
str instanceof Object // false
let tr = true
tr instanceof Boolean // false
tr instanceof Object // false
结果有点出乎意料,我num、str不是也可以访问对应的原型链上的方法,所以它Object的prototype属性应该在num还有str原型链上面,但是测试出的结果为什么是false呢,是我对str.__proto__ === String; str.__proto__.__proto__ === Object.prototype
的理解有误吗,既然如此,那么就打开控制台测试一下:
let str = 'str'
str instanceof String // false
str instanceof Object // false
str.__proto__ === String.prototype // true
str.__proto__.__proto__ === Object.prototype // true
这个结果让之前的理解变得扑朔迷离,构造函数String的prototype在实例对象的原型链上,但是str instanceof String为false,为什么呢?所以继续翻MDN的定义,找到了,值类型不是对象,只是在用.访问属性和方法时,创建了个实例对象,是该值类型的包装。在访问属性和方法结束后,实例就结束了,不过字面量创建的对象比较特殊,因为字面量创建的对象,也是对象。
所以字面量创建字符串和构造函数创建的字符串不能用来比较,之前的代码输出的内容也是很合理的。
let str = 'str'
str instanceof String // fasle
let str1 = new String()
str1 instanceof String // true