javascript:object

javascript:object

本文关键字:object javascript      更新时间:2023-09-26

最后,我在下面的代码中看到了一股关闭的味道。

function create(parent) {
var F = function() {};
 F.prototype = parent;
return new F();
}
var masterObject = {a: "masterObject value"}
var object1 = create(masterObject);
var object2 = create(masterObject);
var object3 = create(masterObject);
var object3.a = "overridden value";
object1.a; // "masterObject value"
object2.a; // "masterObject value"
object3.a; // "overridden value"
masterObject.a = "new masterObject value"//value is changed now
object1.a; // "new masterObject value"
object2.a; // "new masterObject value"
object3.a; // "overridden value"

object1.a,abject2.a的值被永久地改变。这是因为我在全局变量中做了一个改变,还是这是闭包的影响?既然我没有再次调用Create((函数,为什么值会自动更改?最后一个问题是"当我更改全局变量时,这会自动影响使用tht变量的所有对象吗?"在我看来,为了影响该变量,我应该再次调用Create((函数,不是吗?

访问object3.a时,JavaScript首先查看对象的属性。如果对象没有名为a的属性,那么接下来将检查对象的原型。

设置object3.a = "overridden value";会给object3一个名为a的属性。它不会影响原型的a属性。

由于object1object2没有名为a的属性,但它们的原型有,因此当您修改masterObjecta属性时,所有以masterObject为原型的对象的值都会全局更改。

尽管您为object3提供了一个名为a的属性,但您仍然可以访问原型的a属性,该属性保持不变:

object3.__proto__.a; // "new masterObject value"

基本上,通过给object3一个名为a的属性,您就把对象的新属性"放在"原型的属性前面。

当您直接更改对象的'a'属性时(就像您对var object3.a = "overridden value";(它前面不应该有var(所做的那样(,您会更改该实例自己的'a'特性。

所以,真正发生的是:

object3.a = "overridden value";在这里在object3上创建一个新属性。它以前没有"a"属性。然而,它的原型确实如此,因此object3.a是合法的,并将引用原型的"a"属性。

masterObject.a = "new masterObject value"在这里更改所有对象的原型(由create()创建(。因此,如果您访问对象的属性"a",它现在将被更改,除了那些具有自己的"a"属性的对象(如对象3(。

这是因为继承在基于原型的语言(如javascript(中的工作方式。当您调用create(masterObject)时,您将返回一个函数对象的新实例(您称之为F(,其原型设置为masterObject。这意味着object1object2object3的原型字段指向同一对象masterObject

声明:

object3.a  = "overriden value"

object3中创建一个名为a的字段,并为其指定字符串"overriden value",这就是检查object3.a时得到的结果。但是,当您查看object1.a时,解释器会注意到object1中不存在a字段,因此它遵循原型链接到其父级,并检查名为a的字段。在这种情况下,原型链接指向masterObject,它有一个名为a的字段,其中包含字符串"masterObject value",这就是您所看到的。如果masterObject没有一个名为a的字段,解释器将一次又一次地跟踪原型链接,直到它找到一个a字段,或者直到它到达一个具有空原型链接的对象,然后它将返回值undefined

因此,通过更改masterObject.a,您可以更改检查object1.aobject2.a时看到的内容,因为object1object2没有一个名为a的字段,所以它们从父级masterObject"继承"了它。

检查object3.a时不会发生这种情况,因为您在object3中创建了一个名为a的字段,该字段包含字符串"overridden value"

如果在代码末尾添加:

delete object3.a;

现在,当您查看object3.a时,您会看到"new masterObject value",因为object3不再有一个名为a的字段,所以它从其父级masterObject"继承"了它。