什么's使用instanceof和检查构造函数之间的区别

What's the difference between using instanceof and checking the constructor?

本文关键字:构造函数 检查 之间 区别 instanceof 使用 什么      更新时间:2023-09-26

为什么以下两行返回的结果不同?

("test" instanceof String) // returns false
("test".constructor == String) // returns true

在铬版本28.0.1500.95 m 的控制台中测试

对于本机类型,它的工作方式是否略有不同?

constructor只是内部[[prototype]]属性的一个属性,可以很容易地进行操作:

function A(){}
function B(){}
A.prototype.constructor = B;
var a = new A();
console.log(a.constructor); //B

然而,instanceof操作符会检查内部原型链,即使您更改了构造函数的完整prototype属性:,它也不会那么容易被欺骗

function A(){}
function B(){}
A.prototype = B.prototype;
var a = new A();
console.log(a instanceof A); //true
console.log(a instanceof B); //false

那么,为什么是"test" instanceof String === false而不是("test".constructor == String) === true呢?

首先,"test"是一个基元,而基元从来都不是任何事物的实例。使用instanceof时实际发生的情况是,构造函数的内部[[HasInstance]]方法是以可能的实例作为参数调用的。因此a instanceof A大致翻译为:

`A.[[HasInstance]](a)`

ECMA规范对[[HasInstance]]说:http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.5.3

[[HasInstance]](V)

假设F是Function对象。

当用值V调用F的[[HasInstance]]内部方法时,采取以下步骤:

  1. 如果V不是对象,则返回false

换句话说:如果instanceof的左手边不是对象,则操作符将返回false。

("test".constructor == String) === true的工作原理不同:如果尝试访问基元的属性,则该基元将临时转换为对象。所以"test".constructor大致等于:

(new String("test")).constructor

在这种情况下,您实际上是在创建一个具有构造函数的对象,然后请求constructor属性。因此,它将返回String也就不足为奇了。

主要区别在于instanceof检查对象的原型链,而检查构造函数只检查它是否是从同一个构造函数创建的。

示例:

function MyObject() {
    this.sayHi = function() { alert('Hi!'); }   
}
var x = new MyObject();
alert(x.constructor === Object);
alert(x instanceof Object);