gpt4 book ai didi

javascript - Crockford 风格的原型(prototype)模式陷阱;寻找一个优雅的解决方案

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:36:58 25 4
gpt4 key购买 nike

我在编写 JavaScript 程序时经常使用 Crockford 的原型(prototype)模式。我以为我了解所有涉及的“陷阱”,但我发现了一个我以前没有想过的问题。我想知道是否有人有处理它的最佳实践。

这是一个简单的例子:

// Here's the parent object
var MyObject = {
registry: {},
flatAttribute: null,
create: function () {
var o, F = function () {};

F.prototype = this;
o = new F();
return o;
}
};

// instance is an empty object that inherits
// from MyObject
var instance = MyObject.create();

// Attributes can be set on instance without modifying MyObject
instance.flatAttribute = "This is going to be applied to the instance";

// registry doesn't exist on instance, but it exists on
// instance.prototype. MyObject's registry attribute gets
// dug up the prototype chain and altered. It's not possible
// to tell that's happening just by examining this line.
instance.registry.newAttribute = "This is going to be applied to the prototype";

// Inspecting the parent object
// prints "null"
console.log(MyObject.flatAttribute);
// prints "This is going to be applied to the prototype"
console.log(MyObject.registry.newAttribute);

我想确保对实例所做的任何更改都不会向上传播继承更改。当属性是一个对象并且我正在设置嵌套属性时,情况就不是这样了。

解决方案是重新初始化实例上的所有对象属性。但是,使用此模式的优点之一是从构造函数中删除重新初始化代码。我正在考虑克隆父对象的所有对象属性并将它们设置在 create() 函数中的实例上:

{ create: function () {
var o, a, F = function () {};

F.prototype = this;
o = new F();
for (a in this) {
if (this.hasOwnProperty(a) && typeof this[a] === 'object') {
// obviously deepclone would need to be implemented
o[a] = deepclone(this[a]);
}
}
return o;
} };

有没有更好的办法?

最佳答案

有一个非常简单的解决方案可以确保它们只是实例变量,那就是在构造函数中使用 this 关键字。

var MyObject = {
flatAttribute: null,
create: function () {
var o, F = function () {
this.registry = {}
};

F.prototype = this;
o = new F();
return o;
}
};

这确保了“instance.registry.*”的所有属性对于实例都是本地的,因为 javascript 对象的查找顺序如下。

object -> prototype -> parent prototype ...

因此,通过在名为“registry”的构造函数中向实例添加一个变量,该变量将始终被首先找到。

另一个我认为更优雅的解决方案是不使用 crockford 的(java 样式)构造函数并使用更自然地反射(reflect) javascripts 对象系统的布局。大多数问题都源于实践与语言之间的不匹配。

// instance stuff
var F = function () {
this.registry = {}
};

F.prototype = {
// static attributes here
flatAttribute: null,
methodA: function(){
// code here 'this' is instance object
this.att = 'blah';
}
};

var instanceA = new F();
instanceA.registry['A'] = 'hi';
var instanceB = new F();
instanceB.registry['B'] = 'hello';

instanceA.registry.A == 'hi'; // true
instanceB.registry.B == 'hello'; // true
F.prototype.registry == undefined; // true

关于javascript - Crockford 风格的原型(prototype)模式陷阱;寻找一个优雅的解决方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5596271/

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