2014-02-10 40 views
0

我正在構建一個國際象棋應用程序,並且遇到了有關JavaScript中對象定義和實例化之間差異的問題。例如,我想我Board模型(以及視圖)與它的表示(嵌套數組)通過Matrix模型分開:如何在JavaScript中處理對象定義與實例化?

var Matrix = function(n, m) { 
    // builds an n*m nested array 
    // e.g. a 2x3 array would look like this: 
    // [[0, 0], [0, 0], [0, 0]] 
}; 

// A setter, which takes a `Point` object and correctly updates the nested array 
Matrix.prototype.set = function(pt, obj) { 
    this.state[pt.y][pt.x] = obj; 
}; 

// A custom `each` method that iterates over the nested array 
Matrix.prototype.each = function(fn) { 
    // executes `fn` against every (x,y) in the nested array 
}; 

// etc. 

然後Board看起來是這樣的:

var Board = function(n, m) { 
    Matrix.call(this, n, m); 

    // now use `Matrix`'s `set` method to place pieces on the board. 
}; 

Board.prototype = Matrix.prototype; 

// etc. 

我的問題真的在Board的定義。當我實例化一個新的Board對象時,我想要它的子類Matrix,然後使用Matrix的方法在板上設置棋子。但問題是Board在實例化時無法訪問Matrix的方法,因爲該關係仍在定義中。

試圖解決此問題已澄清了this question的答案。看起來問題是Board不是Matrix的真實子類。直到代碼實際執行時纔會設置該關係。什麼是處理這種關係的JavaScript式的方式?

+1

'Board.prototype = Matrix.prototype;'是一個壞主意。你需要'Board.prototype = Object.create(Matrix.prototype);'(如果Object.create的功能的相關子集需要填充shim)。 –

回答

2

但問題是,董事會在實例化時無法訪問Matrix的方法,因爲該關係仍在定義中。

號當您使用Boardnew operator,那麼首先的關係(「原型鏈」)將被定義後,該Board構造函數將在新的實例調用,它可以調用Matrix函數或添加實例屬性,如.state。您可以使用原型繼承的set方法,在那裏沒有任何問題。

看着Why is inheritance only defined at compile-time?

在JavaScript中,繼承是在運行時設置。你可以聲明函數體(使用繼承的方法),然後設置原型,然後實例化對象。

Board.prototype = Matrix.prototype; 

Don't do that。你想要Board.prototype = Object.create(Matrix.prototype)

+2

我並沒有看到在這方面降薪的原因,Bergi對你真正嘗試使用Board的構造函數時會發生什麼非常正確。 –

+0

我不認爲這個答案值得downvotes。我假設*「...將在新實例上調用構造函數*」引用矩陣構造函數。 –

+0

@cookiemonster:我確實提到了Board的構造函數。確實,它叫'矩陣'。 – Bergi

2

這是不正確的:

Board.prototype = Matrix.prototype; 

做到這一點,而不是讓補充Board.prototype不影響Matrix.prototype

Board.prototype = Object.create(Matrix.prototype); 

現在Board.prototype是一個空對象從Matrix.prototype繼承。


我看不出爲什麼你的對象從Board創建不會有從Matrix.prototype訪問方法,所以我會假設你或許覆蓋或遮蔽的Matrix.prototype方法。

// etc.部分代碼可能是問題所在。