ECMAScript 5 已经为构造和继承定义了一个非常常见的工厂模式,称为Object.create()。我只是将对象传递给 继承并回来一个新对象都正确连线。
考虑一下代码段:
var a = {
phrase: "Hello",
say: function(){ alert(this.phrase); }
};
var b = Object.create(a);
我的理解是否正确如下所示?
首次创建b时,它具有一个名为的原型继承属性 短语,意味着该属性不在实例上(b.phrase), 但实际上是在原型上(b.prototype.phrase)。如果我去的话 在那时读取b.phrase的值,JavaScript会隐式地 查一查,在原型上找到它,然后把它还给我。
b.say(); // alerts Hello
但是,当我为b.phrase分配一个新值时,我发现它不会影响继承 b.prototype.phrase但是设置(覆盖)一个优先于继承的实例属性b.phrase b.prototype.phrase关于未来的财产访问。为什么呢?
b.phrase = "World";
a.say(); // alerts Hello >> This hasn't changed. Why?
b.say(); // alerts World
答案 0 :(得分:3)
这是因为原型链。 JavaScript运行时首先查找自己的对象的属性,如果找不到任何内容,它会在其原型上查找属性,依此类推。
另一方面,你不是覆盖一个属性,但你只是在整个对象中添加一个,它隐藏原型'一个又一个,这是因为原型链的工作原理。
答案 1 :(得分:2)
这是javascript属性查找/分配工作的方式。如果要更新prototype属性,可以在prototype对象中创建对象。
var proto = {
fields: {
phrase: 'Hello'
},
say: function () { console.log(this.fields.phrase) }
};
var a = Object.create(proto);
a.fields.phrase = 'World';
proto.say();
a.say();
那么,这里发生了什么?
a.fields.phrase = 'World'
等于
var tmp = a.fields;
tmp.phrase = 'World';
a.fields === a.__proto__.fields // true
这就是为什么在原型中更新了属性。
在你的例子中,你只需为对象分配值,js引擎就可以做你想要的 - 用对象“短语”给对象分配值“World”,没什么奇怪的
答案 2 :(得分:0)
首先采取此声明
var b = Object.create(a);
此语句创建一个新对象newObj
(例如)。现在发生以下事情:
b指向newObj
。
newObj通过[[prototype]]
引用链接到对象。
直到现在newObj
没有任何方法或属性。
选择b.Say()
- b将指向newObj
,因此首先它会尝试检查newObj
是否有Say()
方法,它不会因此它试图通过[[prototype]]
链委托。由于newObj's
[[prototype]]
链接指向某个对象。它试图检查对象中是否存在Say()
。因此,它找到了那里的方法&使用newObj.
的上下文执行它打印'Hello'
取b.Phrase='world'
在这里,您要将phrase
属性分配给newObj
对象(由' b'指向)。因此,从下次开始,如果您尝试执行b.Phrase
,它将不会遍历[[Prototype]]
链(即对象的对象),而是会在newObj
中找到值本身。
Final b.Say()
由于newObj
没有Say()
方法,它会遍历[[prototype]]
链,找到方法,&在newObj
的上下文中执行它。由于newObj
具有词组属性,因此this.phrase
会返回'world'