2012-12-15 115 views
0

我試圖將this.SOME_MEMBER傳遞給方法,但它不會像同一個成員一樣通過。下面的代碼應該對我想要了解的東西更有意義。將對象成員(如this.member)傳遞給javascript中的類方法

function App() 
{ 
    this.canvas = new Object(); 
} 

App.prototype.createCanvas = function(obj, width, height) 
{ 
    obj = document.createElement('canvas'); 
    obj.setAttribute('width', width); 
    obj.setAttribute('height', height); 

    log(obj == this.canvas); //false 
    log(this.canvas == app.canvas); //true 
            //it's clear that this refers to app 

    //so why doesn't obj refers to this.canvas? 
    //how do i get obj to equal this.canvas? 
} 

App.prototype.init = function() 
{ 
    this.createCanvas(this.canvas, 800, 600); 
    log(this.canvas.width); //undefined 
} 

var app = new App(); 
app.init(); 

現在,我知道我可以只是簡單地做到以下幾點:

function App() 
{ 
    this.canvas = new Object(); 
} 

App.prototype.createCanvas = function(width, height) 
{ 
    this.canvas = document.createElement('canvas'); 
    this.canvas.setAttribute('width', width); 
    this.canvas.setAttribute('height', height); 
} 

App.prototype.init = function() 
{ 
    this.createCanvas(800, 600); 
    log(this.canvas.width); //800 
} 

var app = new App(); 
app.init(); 

這將適用於大多數應用程序,但我只限於命名變量this.canvas。我最終需要這種方法更靈活一些。

請記住,我使用函數document.createElement和element.setAttribute作爲一個例子;他們可以被替換爲修改變量obj的任何東西。


因此,當「this.canvas」被用作參數時,它會發生什麼?我將如何實現我期待的目標?

在此先感謝!

+0

我已經更新了我的答案,很抱歉第一次誤解了這個問題。 –

回答

2

那麼爲什麼不obj指的是這個可愛的?

因爲你在函數中完成的第一件事就是給它,而不是不同的值:

App.prototype.createCanvas = function(obj, width, height) 
{ 
    obj = document.createElement('canvas'); 
// ^------------------------------------------ here 
    obj.setAttribute('width', width); 
    obj.setAttribute('height', height); 

    log(obj == this.canvas); //false 
    log(this.canvas == app.canvas); //true 
            //it's clear that this refers to app 

    //so why doesn't obj refers to this.canvas? 
    //how do i get obj to equal this.canvas? 
} 

JavaScript是一種純粹的傳遞按值語言。 obj參數的您通過(其來自this.canvas,因爲這是您在調用它時給的); obj不是對this.canvas屬性的引用。要按照你想要的方式做你想做的事情,需要通過引用來傳遞this.canvas(屬性),這是你在JavaScript中無法做到的。 (不過,見下文)。

現在,我知道我可以只是簡單地做到以下幾點:

(略碼)

這將適用於大多數應用程序,但我限制命名變量爲this.canvas。我最終需要這種方法更靈活一些。

這是一個有些奇怪的要求(當然所有App情況下,應具備的畫布canvas),但如果你希望能夠告訴createCanvas,使對象在什麼性質的畫布上,你可以這樣做:

JavaScript支持兩種引用對象屬性的方法:使用文字的點符號(this.canvas)和使用字符串的括號表示法(this["canvas"])。在後一種情況下,字符串不一定是文字,它可以是包含變量引用的任何經驗的結果  —。

所以你createCanvas變爲:

App.prototype.createCanvas = function(propName, width, height) 
{ 
    // Create the canvas 
    var obj = document.createElement('canvas'); 
    obj.setAttribute('width', width); 
    obj.setAttribute('height', height); 

    // Save that canvas to the given property 
    this[propName] = obj; 
} 

,你這樣稱呼它:

App.prototype.init = function() 
{ 
    this.createCanvas("canvas", 800, 600); 
} 

這就是說,它會是相當更直接的只是createCanvas回報畫布所以呼叫代碼可以放在任何地方:

App.prototype.createCanvas = function(width, height) 
{ 
    // Create the canvas 
    var obj = document.createElement('canvas'); 
    obj.setAttribute('width', width); 
    obj.setAttribute('height', height); 
    return obj; 
} 

然後

App.prototype.init = function() 
{ 
    this.canvas = this.createCanvas(800, 600); 
} 

旁註:你錯過了分號,當你有x = ...它需要一個;底,即使..是一個函數表達式。因此,例如,在App.prototype.init = ...需要;底:

App.prototype.init = function() 
{ 
    this.canvas = this.createCanvas(800, 600); 
}; // <=== Here 

它不會導致因爲那是automatic semicolon insertion恐怖的語法錯誤,但我強烈建議不要依賴於它的邊緣情況在最不經意的時候,錯誤的東西會咬你(而且最不能承受)。總是包含正確的分號可以節省時間。

0

你的線,

obj = document.createElement('canvas'); 

覆蓋傳遞到createCanvas方法obj變量,並將其設置爲完全的新對象。變量分配會中斷前一個引用,並創建對新對象的新引用。 obj變量是對另一個對象的引用。你不能用它來改變引用的對象成爲一個完全不同的對象。

如果您通過調用方法或更改屬性來對obj變量進行操作,則這些操作都將對原始對象起作用。因此,也許將this對象傳遞給該方法(儘管這似乎沒有意義,除非您打算在不同範圍內調用該函數)。