Два экземпляра содержат одинаковые значения - PullRequest
1 голос
/ 17 марта 2012

Я сталкиваюсь с причудливой ошибкой при попытке создать объект 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 ]

5 голосов
/ 17 марта 2012

Вы определяете items внутри своего прототипа, что означает, что он будет использоваться всеми экземплярами.Вам нужно установить его внутри функции «Конструктор» и удалить его из прототипа.

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

Я создал для вас JS Fiddle с полным исходным кодом http://jsfiddle.net/brunomsilva/zaSY2/.

3 голосов
/ 17 марта 2012

Свойство items установлено на prototype.Прототип не клонируется при создании объекта, поэтому items одинаково на двух Dict с.Установите в конструкторе items, чтобы у каждого объекта был свой собственный:

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

Прототипы работают, потому что когда вы пытаетесь получить доступ к свойству объекта, он сначала проверяет собственные свойства объекта, чтобы увидеть, содержит ли он его.Если так, то это ценность.Если его там нет, он проверяет прототип.Если его там нет, он продолжает пересекать цепочку прототипов, пока не найдет собственность.Если это все еще не найдено, это приводит к undefined.(более подробно см. спецификацию )

2 голосов
/ 17 марта 2012

, чтобы определить класс для использования, попробуйте переместить определения функций в прототип без замены объекта-прототипа, например так:

     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);
            });
        };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...