ECMAScript 5定义了用于构造和继承的通用工厂模式[Object.create()]

ECMAScript 5 defined - common factory pattern for construction and inheritance, [ Object.create()]

本文关键字:模式 工厂 Object create 定义 用于 继承 ECMAScript      更新时间:2023-09-26

ECMAScript 5为构造和继承定义了一个非常常见的工厂模式,名为Object.create()从继承,并返回一个新对象,所有这些都已正确连接。

考虑一下这个片段:

var a = {
    phrase: "Hello",
    say: function(){ alert(this.phrase); }
};
var b = Object.create(a);

我的理解是否正确,如下所示?

当b第一次创建时,它有一个原型继承属性,称为短语,意思是属性不在实例上(b.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

这是因为原型链。JavaScript运行时首先查找自己对象的属性,如果什么都找不到,则在其原型上查找属性,依此类推

另一方面,您并不是覆盖属性,而是向整个对象添加一个属性,而隐藏了原型的属性,同样,这是因为原型链的工作方式。

这是javascript属性查找/分配的工作方式。若要更新原型属性,可以在原型对象内部创建对象。

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"分配给对象a,没有什么奇怪的

有关对象如何在js 中工作的更多信息

首先执行以下语句

var b = Object.create(a);

此语句创建一个新对象newObj(例如)。现在发生了以下事情:

  • b指向CCD_ 4。

  • 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]]链(即到a的对象),而是会在newObj本身中找到值。

Final b.Say()
由于newObj没有Say()方法,它将遍历[[prototype]]链,找到该方法,&在CCD_ 27的上下文中执行它。由于newObj具有短语属性,因此this.phrase返回'world'