gpt4 book ai didi

javascript - instanceof 在 JavaScript 中如何工作?

转载 作者:数据小太阳 更新时间:2023-10-29 04:26:15 25 4
gpt4 key购买 nike

在下面的代码示例中,在末尾使用 instanceof 检查 obj2 和 obj3 都返回 true,即使它们的构造方式不同,返回 name 的结果也是如此属性不同。

var Obj1 = function() {
this.name = "foo1";
};
Obj1.prototype.name = "foo1onProt";
var obj1 = new Obj1();

var Obj2 = function() {};
Obj2.prototype = new Obj1();
Obj2.prototype.constructor = Obj2;
var obj2 = new Obj2();

var Obj3 = function() {};
Obj3.prototype = Object.create(Obj1.prototype);
Obj3.prototype.constructor = Obj3;
var obj3 = new Obj3();

console.dir(obj1);
console.log("obj1.name: " + obj1.name);

console.dir(obj2);
console.log("obj2.name: " + obj2.name);

console.dir(obj3);
console.log("obj3.name: " + obj3.name);

console.log("obj2 instanceof Obj1: " + (obj2 instanceof Obj1));
console.log("obj3 instanceof Obj1: " + (obj3 instanceof Obj1));

在 Chrome 中运行的结果:

Obj1
name: "foo1"
__proto__: Object
constructor: function () {
name: "foo1onProt"
__proto__: Object
obj1.name: foo1
Obj2
__proto__: Obj1
constructor: function () {}
name: "foo1"
__proto__: Object
constructor: function () {
name: "foo1onProt"
__proto__: Object
obj2.name: foo1
Obj3
__proto__: Object
constructor: function () {}
__proto__: Object
constructor: function () {
name: "foo1onProt"
__proto__: Object
obj3.name: foo1onProt

obj2 instanceof Obj1: true
obj3 instanceof Obj1: true

识别 obj2obj3 不同的最佳方法是什么?instanceof 实际上是如何工作的?

最佳答案

What is the best way to recognize that obj2 and obj3 are different?

这在很大程度上取决于您对它们所做的事情。一种方法是使用 instanceof Obj2instanceof Obj3。由于这两个对象都是在其原型(prototype)链中使用 Obj1.prototype 创建的,因此将它们标识为我们在基于类的 OOP 中称为父类(super class)型的实例是有道理的。

How does actually instanceof work?

简短版

obj instanceof F 查看 F.prototype 引用的对象是否在 obj 的原型(prototype)链中的任何位置。它根本不使用 constructor

更多详情

§11.8.5 - The instanceof Operator 的规范中涵盖了这一点,它表示(间接地,通过 §8.6.2 )它调用函数对象的 [[HasInstance]] 内部方法,传入我们正在测试的对象。 Function[[HasInstance]](在 §15.3.5.3 中)表示它从函数的 prototype 属性获取对象引用,然后返回true 如果该对象在目标对象的原型(prototype)链中的任何位置,则为 false

它不使用 constructor(事实上 JavaScript 本身没有)——如果你仔细想想,它不能,因为一个对象的 constructor属性只能指向一个函数,但一个对象可以是instanceof多个函数——例如,在伪经典继承的情况下:

function F1() {}

function F2() {
F1.call(this);
}
F2.prototype = Object.create(F1.prototype);
F2.prototype.constructor = F2;

var obj = new F2();
console.log(obj instanceof F1); // true
console.log(obj instanceof F2); // true

两者都是真的,因为 F1.prototypeF2.prototype 引用的两个对象都在 obj 的原型(prototype)链中。

instanceof 为真并不一定意味着 obj 是通过调用 F 直接或间接创建的;它只是表明它们之间存在模糊的联系(F.prototype 指的是也在 obj 的原型(prototype)链中的对象)。它通常意味着 F 参与了对象的创建,但不能保证。

例如:

function F() {}
var obj = Object.create(F.prototype);
console.log(obj instanceof F); // true

请注意,根本没有调用 F 来创建对象。


或者更清楚和/或更戏剧化:

function F() {}
var p = {};
var obj = Object.create(p);
console.log(obj instanceof F); // false
F.prototype = p;
console.log(obj instanceof F); // true


还有这个不寻常但完全可能的版本:

function F1() {}
function F2() {}
F1.prototype = F2.prototype = {};
var obj = new F1();
console.log(obj instanceof F2); // true


或者这个:

function F1() {}
function F2() {}
var obj = new F2();
console.log(obj instanceof F1); // false
F1.prototype = F2.prototype;
console.log(obj instanceof F1); // true

关于javascript - instanceof 在 JavaScript 中如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24453301/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com