获取下面的给定代码并将其与之后的代码进行比较:
var protoShoe = {isShoe:true, isGenderSpecific: false}
protoShoe = Object.create(protoShoe);
protoShoe.isGenderSpecific= true; protoShoe.gender = "mens";
protoShoe = Object.create(protoShoe);
protoShoe.isGenderSpecific= false; protoShoe.gender = "na";
console.log("Is protoShoe prototype of protoShoe:" + protoShoe.isPrototypeOf(protoShoe));
console.log(protoShoe);
VS
var protoShoe = {isShoe:true, isGenderSpecific: false}
mensShoe = Object.create(protoShoe);
mensShoe.isGenderSpecific= true; mensShoe.gender = "mens";
protoShoe = Object.create(mensShoe);
protoShoe.isGenderSpecific= false; protoShoe.gender = "na";
console.log("Is mensShoe prototype of protoShoe:" + mensShoe.isPrototypeOf(protoShoe));
console.log(protoShoe);
最终对象在其继承属性中看起来非常相似,但在第一种情况下,我们只是继续重用protoShoe
对象,最后它不是自身的原型,这是为什么?如果是这样会导致任何问题吗?
我只是想更好地理解原型继承,这只是一个愚蠢的实验,但我发现第一个的isPrototypeOf
值很有趣。
答案 0 :(得分:3)
您创建的protoShoe
变量是对对象的引用。当您protoShoe = Object.create(protoShoe);
创建新对象并覆盖引用时。它不是同一个对象,即使它被称为相同。旧protoShoe
仍然存在,但现在唯一引用它的是新protoShoe
的原型。
基本上你重复使用的是变量的名称,而不是对象。
无法创建一个自身原型的对象。至少在我检查过的任何JS运行时。由于属性查找的工作原理,它会创建一个无限循环。
如果你有一个对象,比如protoShoe
,并希望在其上查找一个属性,比如notAShoeProperty
,JS首先检查对象本身是否有该属性。如果找不到它,它会查找原型链。如果它没有在原型上找到它,它会查看原型的原型等等。因此,如果你有一个对象是它自己的原型,试图找到一个未定义的变量会导致无限循环。
我知道实际尝试创建这样一个原型链的唯一方法是protoShoe.__proto__ = protoShoe
。 V8抱怨循环原型值然后抛出错误。