我无法理解PrototypeJS多类实例。
这是我的代码示例:
var Test = Class.create();
Test.prototype = {
settings: {
a: {},
b: {},
},
initialize: function(options) {
this.settings.c = options.c;
}
};
var a = new Test({c: 1});
console.log(a.settings);
var b = new Test({c: 2});
console.log(a.settings);
var c = new Test({c: 3});
console.log(a.settings);
<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.2/prototype.min.js"></script>
预期结果: a.settings应包含值为“1”的“c”项。
实际结果: a.settings“c”等于“3”。
(注意,您需要在开发工具中展开对象才能看到它。)
为什么呢?我错过了什么,或者它是某种PrototypeJS错误?创建隔离类实例的正确方法是什么?
答案 0 :(得分:1)
每个实例共享相同的this.settings
对象。必须在构造函数中初始化可变数据结构,而不是在原型上:
Test.prototype = {
initialize: function(options) {
this.settings = {
a: {},
b: {},
c: options.c;
};
}
};
请注意,这似乎是“传统方式”(根据文档),更新的方式是:
var Test = Class.create({
initialize: function(options) {
this.settings = {
a: {},
b: {},
c: options.c;
};
}
});
实际上解决了这个问题
编程语言中的继承类型
通常我们区分基于类和原型的继承,后者特定于JavaScript。
原型继承当然是该语言非常有用的功能,但在实际创建对象时通常很冗长。这就是我们通过内部原型继承模拟基于类的继承(如在Ruby语言中)的原因。这有一定的影响。
[...]
我们可以尝试在Prototype中做同样的事情:
var Logger = Class.create({ initialize: function() { }, log: [], write: function(message) { this.log.push(message); } }); var logger = new Logger; logger.log; // -> [] logger.write('foo'); logger.write('bar'); logger.log; // -> ['foo', 'bar']
有效。但是,如果我们创建另一个Logger实例呢?
var logger2 = new Logger; logger2.log; // -> ['foo', 'bar'] // ... hey, the log should have been empty!
您可以看到,虽然您可能期望新实例中有一个空数组,但它与前一个logger实例具有相同的数组。实际上,所有记录器对象都将共享同一个数组对象,因为它是通过引用而不是按值复制的。
而是使用默认值初始化您的实例:
var Logger = Class.create({ initialize: function() { // this is the right way to do it: this.log = []; }, write: function(message) { this.log.push(message); } });