两个实例包含相同的值

时间:2012-03-17 00:34:00

标签: javascript inheritance

我在尝试创建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());

3 个答案:

答案 0 :(得分:5)

您在原型中定义items,这意味着它将由所有实例共享。您需要在“构造函数”函数中设置它并将其从原型中删除。

function Dict() { this.items = []; }

我使用http://jsfiddle.net/brunomsilva/zaSY2/的完整源代码为您创建了一个JS小提琴。

答案 1 :(得分:3)

items上设置prototype属性。创建对象时不会克隆原型,因此itemsDict上是相同的items。在构造函数中设置function Dict() { this.items = {}; } ,以便每个对象都有自己的:

undefined

原型是有效的,因为当您尝试访问对象的属性时,它首先检查对象自己的属性以查看它是否包含它。如果是这样,那就是价值。如果在那里找不到它,它会检查原型。如果不存在,它会继续遍历原型链,直到找到属性。如果仍未找到,则会生成{{1}}。 (更多细节,see the specification

答案 2 :(得分:2)

定义要使用的类,尝试将函数定义移动到原型而不替换原型对象,如下所示:

     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);
            });
        };