gpt4 book ai didi

javascript - 原型(prototype)中的对象作为引用被继承

转载 作者:行者123 更新时间:2023-11-29 15:43:04 25 4
gpt4 key购买 nike

我想使用原型(prototype)继承新的对象实例。

测试用例:

var MyObj = function() {}
MyObj.prototype.objName = {}
// I want this to be a different object for each instance of MyObj

var o1 = new MyObj (),
o2 = new MyObj ();

o1.objName['a'] = 1;
o2.objName['a'] = 2;

alert(o1.objName['a']) // 2
alert(o1.objName === o2.objName) // true

这意味着原型(prototype)中的对象不是作为其副本而是作为其引用继承的。

我知道通常你可以这样做。

var MyObj = function() {
this.objName = {}
}

var o1 = new MyObj(),
o2 = new MyObj();

alert(o1.objName === o2.objName) // false

这工作正常,但在我的情况下,这不是一个选项。我确实需要在 MyObj 函数之外定义 objName。

我设法“解决”了这个问题

MyObj.prototype.objName = function() {
if ( this._objName === undefined ) {
this._objName = {};
}
return this._objName;
}

var o1 = new MyObj(),
o2 = new MyObj();

o1.objName()['a'] = 1;
o2.objName()['a'] = 2;

alert(o1.objName()['a']) // 1

但这不是很漂亮,这段代码的性能更差。

有什么办法可以更优雅地解决这个问题吗?

最佳答案

This means that objects in prototype are not inherited as its copies but instead as its reference.

原型(prototype)上的任何内容都不会被复制 - 原型(prototype)继承的整个概念是属性引用原型(prototype)对象的共享属性。因此,如果您希望每个实例的属性都是独立的,则必须将其显式分配给对象并隐藏原型(prototype)属性;就像您在代码中使用 _objName 属性一样。

But this is not very pretty and the performance of this code is much worse.

如果你想要它漂亮,把它移到构造函数(或者让构造函数寻找类似 init 的方法来调用,如果存在的话,那么你可以在原型(prototype)上创建那个 init 方法。

为了让性能好一点,可以把getter函数改成

MyObj.prototype.getObj = function() {
var obj = {};
this.getObj = function(){ return obj; }; // overwrite itself
return obj;
};

虽然它仍然有函数调用开销。为了更加优雅,您可以使用在第一次访问时删除自身的 getter 属性(旧浏览器不支持):

Object.defineProperty(MyObj.prototype, "objName", {
get: function() {
var obj = {};
Object.defineProperty(this, "objName", {
value: obj,
writable: true //?
});
return obj;
},
enumerable: true,
configurable: true
});

现在您可以省略函数调用括号。

关于javascript - 原型(prototype)中的对象作为引用被继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15987397/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com