2010-07-28 58 views
0

我使用原型繼承並希望擁有實例數組的對象。所以如果我用一個實例數組從一個對象派生出一些對象並訪問這個數組,所有這些對象都共享這個數組。我想推動一些東西到數組中,只改變實際對象中的數組,而不是所有其他數組。原型繼承和實例數組的問題

使用標準原型繼承和Object.create,這個問題的優先解決方案是什麼?

var sys = require('sys'); 

var obj ={ 
    data: [], 
    add: function(what){ 
     this.data.push(what) 
    } 
}; 

var one = Object.create(obj); 
one.add(1); 

var other = Object.create(obj); 
other.add(2); 

sys.puts(other.data.length); // is 2, but should be 1 

回答

2
var ObjectName = function(){ 
    this.data = []; 
} 

ObjectName.prototype.add = function(what){ 
    this.data.push(what); 
}; 

var one = new ObjectName(); 
one.add(1); 
+0

我想用Object.create – Peterfia 2010-07-28 15:06:50

+0

使用原型繼承。您仍然可以使用object.create。但是你必須運行構造函數來初始化帶有實例變量this.data的對象。 var one = Object.create(ObjectName.prototype); ObjectName.call(one); one.add(1); – Marco 2010-08-15 00:34:42

1

沒有與Object.create沒有優雅的解決方案,因爲你就錯了。

你想要的是:

function MyArray() { 
    this.data = []; // per-instance data here 
} 

MyArray.prototype = { 
    add: function(what) { // prototype methods here 
     this.data.push(what); 
    } 
}; 

var one = new MyArray; 
one.add(1); 
... 
0

您也可以替換:

add: function(what) { // prototype methods here 
    this.data.push(what); 
} 

add: function(what) { // prototype methods here 
    this.data = this.data.concat(what); 
} 

,因爲這將創造的,而不是將其推入它的一個新的變量原型的實例。

0

Object.create可以通過向屬性描述符傳遞第二個參數來爲新對象添加屬性。

var sys = require('sys'); 

var obj = { 
    add: function(what){ 
     this.data.push(what) 
    } 
}; 

var one = Object.create(obj, { 
    data: { 
     value: [], 
     writable: true, 
     enumerable: true, 
     configurable: true 
    } 
}); 
one.add(1); 

var other = Object.create(obj, { 
    data: { 
     value: [], 
     writable: true, 
     enumerable: true, 
     configurable: true 
    } 
}); 
other.add(2); 

sys.puts(other.data.length); // should be 1 

當然,你會希望把他們在設計器功能,所以你不要重複自己:

function makeThing() { 
    return Object.create(obj, { 
     data: { 
      value: [], 
      writable: true, 
      enumerable: true, 
      configurable: true 
     } 
    }); 
} 

雖然,在點基本上你寫一個構造函數(與好處是你不需要用新的稱呼)。此外,如果你設置writableenumerableconfigurabletrue,你可以只設置屬性以正常的方式,這可以通過實施Object.create一個簡單的版本進行使用的ECMAScript 3向後兼容:

function makeThing() { 
    var newObj = Object.create(obj); 
    newObj.data = []; 
    return newObj; 
}