2012-03-17 75 views
1

我在嘗試創建一個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()); 
+0

原型上的對象在所有實例之間共享關於強制正確使用的所有實例 – 2012-03-17 00:46:36

+0

[本文](http://gotochriswest.com/blog/2011/05/17/forcing-a-constructor-in-javascript/)如果你個人不是你的代碼的唯一消費者(或者你只是不信任你自己),那麼構造函數可能會對你感興趣。 – jbabey 2012-03-17 00:49:53

回答

3

items屬性設置在prototype。原型在創建對象時未被克隆,所以items在兩個Dict上是相同的。在構造函數中設置items所以每個對象都有自己:

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

原型工作,因爲當您嘗試訪問對象的屬性,它首先檢查對象自身的屬性,看看它是否包含它。如果是這樣,那就是價值。如果沒有找到,它會檢查原型。如果它不在那裏,它會繼續遍歷原型鏈,直到它找到該屬性。如果仍未找到,則結果爲undefined。 (更多細節,see the specification

+0

>當創建一個對象時,原型沒有被克隆 – Matthew 2012-03-17 00:48:31

+0

而且當時我還以爲我理解了原型。呃! – Matthew 2012-03-17 00:48:53

+1

@Matthew:我添加了一些關於原型*實際*工作原理的更多細節。 – icktoofay 2012-03-17 00:54:17

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

你定義items你的原型中這意味着它將被所有實例共享。您需要將其設置在「構造函數」函數中,並將其從原型中移除。

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

我在http://jsfiddle.net/brunomsilva/zaSY2/創造了一個JS搗鼓你有完整的源代碼。

相關問題