原型javascript
无法理解:原型javascript,javascript,Javascript,无法理解: function Rabbit() { } Rabbit.prototype = { eats: true }; var rabbit = new Rabbit(); Rabbit.prototype = {}; alert(rabbit.eats); //true 及 为什么? 感谢大家的帮助,在“在第一个示例中,您将Rabbit.prototype更改为指向一个全新的、不同的对象。因此,现在Rabbit.prototype和Rabbit。[[Proto]]不再指向同一个对象”(
function Rabbit() { }
Rabbit.prototype = { eats: true };
var rabbit = new Rabbit();
Rabbit.prototype = {};
alert(rabbit.eats); //true
及
为什么?感谢大家的帮助,在“在第一个示例中,您将Rabbit.prototype更改为指向一个全新的、不同的对象。因此,现在Rabbit.prototype和Rabbit。[[Proto]]不再指向同一个对象”(c)T.J.Crowder在第一种情况下,构造的对象仍然与原始prototype对象链接,当然,它仍然具有“吃”的属性
在第二种情况下,您没有引入新的原型,因此更改其“eats”属性的值是通过实例可见的。因为
rabbit
实例后面的原型是在通过new rabbit
创建时分配的(来自rabbit.prototype
),在第一个示例中,您使用一个全新的对象替换Rabbit.prototype
,这对Rabbit
实例没有影响。在第二个示例中,您只需修改现有对象,Rabbit.prototype
和Rabbit
后面的原型都指向该对象,因此由于它们指向同一对象,因此无论您遵循哪个引用,您都可以看到更改
让我们浏览一下var rabbit=new rabbit()代码>(省略一些不相关的细节):
将创建一个新的空白对象
它的底层原型通常称为[[Proto]]
,设置为Rabbit.prototype
。(我之所以说“通常调用”,是因为规范就是这么称呼它的。你不能直接用这个名字访问它。不过,在支持ES5的环境中,你可以通过找到给定对象的名称。一些JavaScript引擎还通过实际调用的非标准属性[在代码中]\uu proto\uu
使其可用)
该新对象被返回并分配给rabbit
现在,我们有两个对象指向原型对象:Rabbit.prototype
,和Rabbit。[[Proto]]
在第一个示例中,您将Rabbit.prototype
更改为指向一个全新的、不同的对象。所以现在Rabbit.prototype
和Rabbit.[Proto]
不再指向同一个对象
在第二个示例中,您只需更改共享对象的属性的值,这样,无论您遵循哪个对象引用,更改都自然可见
基本上与此相同:
var a = {eats: true};
var b = a;
a = {eats: false};
console.log(a.eats); // false
console.log(b.eats); // true
及
相当于
Rabbit.prototype = {};
Rabbit.prototype.eats = true;
及
只需将Rabbit.prototype.eats
false
(从而使先前的赋值无效)
当js引擎查找属性时,如果在本地找不到它的原型(等等),它会使Rabbit.eats
求值为false。?您期望的是什么?基本上说,虽然prototype在objectrabbit
中被分配给了.prototype
,但对象实际上从[[proto]]
中获取了它的属性?那么.prototype
有什么意义呢?@freakish:Rabbit.prototype
只是Rabbit
函数对象的一个属性。它没有什么特别之处,只是newrabbit
表达式使用了该属性。在Rabbit.prototype
和Rabbit
上的[[Proto]]]
属性之间根本没有持久的联系。他们只是碰巧(最初)指向同一个物体。哦,对不起,这让我有点困惑。现在一切都清楚了,谢谢。:)@古怪的:为了你和其他一群人。:-)我认为是函数对象上的属性名起了作用(几年前,这让我最初感到困惑)。如果他们把它称为原型来分配新对象
或者类似的愚蠢行为,那么它可能会更清晰。但更笨重。:-)
var a = {eats: true};
var b = a;
a.eats = false;
console.log(a.eats); // false
console.log(b.eats); // false
Rabbit.prototype = { eats: true };
Rabbit.prototype = {};
Rabbit.prototype.eats = true;
Rabbit.prototype.eats = false;