Javascript ECMAScript 5已定义-用于构造和继承的通用工厂模式,[Object.create()]
ECMAScript 5 为构造和继承定义了一个非常常见的工厂模式,称为Object.create()。我只是将对象传递给 继承并重新获取一个新对象,所有这些都已正确连接 考虑一下这个片段:Javascript ECMAScript 5已定义-用于构造和继承的通用工厂模式,[Object.create()],javascript,inheritance,Javascript,Inheritance,ECMAScript 5 为构造和继承定义了一个非常常见的工厂模式,称为Object.create()。我只是将对象传递给 继承并重新获取一个新对象,所有这些都已正确连接 考虑一下这个片段: var a = { phrase: "Hello", say: function(){ alert(this.phrase); } }; var b = Object.create(a); 我的理解是否正确,如下所示 第一次创建b时,它有一个原型继承属性,名为 短语,表示属性不在实例上(b
var a = {
phrase: "Hello",
say: function(){ alert(this.phrase); }
};
var b = Object.create(a);
我的理解是否正确,如下所示
第一次创建b时,它有一个原型继承属性,名为
短语,表示属性不在实例上(b.短语),
但实际上是在原型上(b.prototype.phrase)。如果我是
读取b.phrase的值时,JavaScript会隐式地
查一下,在原型机上找到,然后还给我
但是,当我将一个新值赋值给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
这是因为原型链。JavaScript运行时首先查找自己对象的属性,如果没有找到任何内容,则在其原型上查找该属性,依此类推
另一方面,您并没有重写属性,但您只是将一个属性添加到整个对象中,它隐藏了原型的一个属性,而且这种情况再次发生是因为原型链的工作方式。这种情况发生是因为原型链。JavaScript运行时首先查找自己对象的属性,如果没有找到任何内容,则在其原型上查找该属性,依此类推
另一方面,您并没有重写属性,只是将一个属性添加到整个对象中,它隐藏了原型的一个属性,而且这种情况再次发生,因为原型链是如何工作的。这是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.uuu proto\uuuuu.fields//true
这就是在原型中更新属性的原因
在您的示例中,您只需将值分配给对象,js引擎就会执行您想要的操作—将带有键“短语”的值“World”分配给对象a,这并不奇怪
这是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.uuu proto\uuuuu.fields//true
这就是在原型中更新属性的原因
在您的示例中,您只需将值分配给对象,js引擎就会执行您想要的操作—将带有键“短语”的值“World”分配给对象a,这并不奇怪
首先接受这句话
var b = Object.create(a);
此语句创建一个新对象,newObj
(例如)。现在发生了以下事情:
- b指向
newObj
- newObj通过
参考链接到a的对象[[prototype]]
newObj
没有任何方法或属性
以b.Say()
--b将指向
newObj
,因此首先它尝试检查newObj
是否有Say()
方法,它没有,因此它尝试通过[[prototype]]
链进行委托。正如newObj的链接指向a的对象一样。它试图检查a的对象中是否存在Say()
。因此它在那里找到方法并在newObj的上下文中执行它。
它打印'Hello'
以
b.Phrase='world'
在这里,您将
短语
属性指定给newObj
对象(由“b”指向)。因此,从下一次开始,如果您尝试执行b.Phrase
,它将不会遍历[[Prototype]]
链(即到a的对象),而是在newObj
本身中找到值
Final b.Say()
由于
newObj
没有Say()
方法,它将遍历[[prototype]]]
链,找到方法,并在newObj
的上下文中执行它。由于newObj
有短语属性,所以这个短语返回'world'
首先接受这个语句
var b = Object.create(a);
此语句创建一个新对象,newObj
(例如)。现在发生了以下事情:
- b指向
newObj
- newObj通过
[[prototype]]
参考链接到a的对象
到目前为止,newObj
没有任何方法或属性
以b.Say()
--
b将指向newObj
,因此首先它尝试检查newObj
是否有Say()
方法,它没有,因此它尝试通过[[prototype]]
链进行委托。正如newObj的链接指向a的对象一样。它试图检查a的对象中是否存在Say()
。因此它在那里找到方法并在newObj的上下文中执行它。
它打印'Hello'
以b.Phrase='world'
在这里,您将短语
属性指定给newObj
对象(由“b”指向)。因此,从下一次开始,如果您尝试执行b.Phrase
,它将不会遍历[[Prototype]]
链(即到a的对象),而是在newObj
本身中找到值
Final b.Say()
由于newObj
没有Say()
方法,它将遍历[[prototype]]]
链,找到方法,并在newObj
的上下文中执行它。正如newObj
具有短语属性,因此this.phrase