两个实例包含相同的值
问题描述:
我在尝试创建一个Dictionary对象时遇到了一个奇怪的错误。很基本的东西。但是,当我创建对象的2个实例,然后设置一个值时,它们出现在两者上。我在这里做错了什么?两个实例包含相同的值
function Dict() { }
Dict.prototype = {
items: { },
prop: function(key) {
return ':' + key;
},
get: function(key, def) {
var p = this.prop(key),
k = this.items;
return k.hasOwnProperty(p) ? k[p] : def;
},
set: function(key, value) {
var p = this.prop(key);
this.items[p] = value;
return value;
},
count: function() {
return Object.keys(this.items).length;
},
has: function(key) {
var p = this.prop(key);
return this.items.hasOwnProperty(p);
},
del: function(key) {
var p = this.prop(key),
k = this.items;
if(k.hasOwnProperty(p))
delete k[p];
},
keys: function() {
return Object.keys(this.items).map(function(key) {
return key.substring(1);
});
}
};
var a = new Dict();
var b = new Dict();
a.set('foo', 'bar');
console.log(a.keys());
console.log(b.keys());
答
的items
属性设置在prototype
。原型在创建对象时未被克隆,所以items
在两个Dict
上是相同的。在构造函数中设置items
所以每个对象都有自己:
function Dict() {
this.items = {};
}
原型工作,因为当您尝试访问对象的属性,它首先检查对象自身的属性,看看它是否包含它。如果是这样,那就是价值。如果没有找到,它会检查原型。如果它不在那里,它会继续遍历原型链,直到它找到该属性。如果仍未找到,则结果为undefined
。 (更多细节,see the specification)
答
定义一个类中使用,请尝试将函数定义为原型而无需更换原型对象,就像这样:
function Dict() {
this.items = {};
}
Dict.prototype.prop = function (key) {
return ':' + key;
};
Dict.prototype.get = function (key, def) {
var p = this.prop(key),
k = this.items;
return k.hasOwnProperty(p) ? k[p] : def;
};
Dict.prototype.set = function (key, value) {
var p = this.prop(key);
this.items[p] = value;
return value;
};
Dict.prototype.count = function() {
return Object.keys(this.items).length;
};
Dict.prototype.has =function (key) {
var p = this.prop(key);
return this.items.hasOwnProperty(p);
};
Dict.prototype.del =function (key) {
var p = this.prop(key),
k = this.items;
if (k.hasOwnProperty(p))
delete k[p];
};
Dict.prototype.keys = function() {
return Object.keys(this.items).map(function (key) {
return key.substring(1);
});
};
答
你定义items
你的原型中这意味着它将被所有实例共享。您需要将其设置在“构造函数”函数中,并将其从原型中移除。
function Dict() { this.items = []; }
我在http://jsfiddle.net/brunomsilva/zaSY2/创造了一个JS捣鼓你有完整的源代码。
原型上的对象在所有实例之间共享关于强制正确使用的所有实例 – 2012-03-17 00:46:36
[本文](http://gotochriswest.com/blog/2011/05/17/forcing-a-constructor-in-javascript/)如果你个人不是你的代码的唯一消费者(或者你只是不信任你自己),那么构造函数可能会对你感兴趣。 – jbabey 2012-03-17 00:49:53