2013-01-09 127 views
2

我想構建一個簡單的應用程序,我將創建一個Box對象的多個實例,它將控制和操作自己的數據。然而,我無法搞清楚如何將每個獨立的對象中創建使用全局變量和它相關的原型......JavaScript變量作用域

例如,我試圖讓自身的參考...

function Box(boxData) { 
    // References the Box instance as I want. 
    console.log(this); 

    // I need to access this later... 
    var boxName = boxData.name; 

    var canvas = $('#rm-' + boxData.id).find('canvas')[0]; 
    $(canvas).on('mousedown', this.onMouseDownHandler); 
} 

Box.prototype.onMouseClickHandler = function(event) { 
    // 'boxName' is undefined as 'this' references 'event.target' 
    console.log(this.boxName); 
} 

請記住,它不能作爲一個單身人士,因爲我會在任何時間點有多個實例。

編輯:

我添加事件偵聽器在構造函數中,更新了上面的代碼。

+0

你是如何執行你的Box.onMouseClickHandler?我認爲你沒有把它綁定正確,但需要一個例子來找出你得到錯誤的地方。請給出一個使用示例。 –

+0

更新了事件監聽器 – user1960364

回答

0

您可以創建全局變量作爲全局對象(窗口)的屬性。您可以使用以下類型:window['box_instance_key']['name']來存儲每個實例的名稱。

function Box(boxData) { 
    // References the Box instance as I want. 
    console.log(this); 

    // I need to access this later... 
    window.boxName = boxData.name; 
    // or something like window[boxData.id]['boxName'] = boxData.name; 
} 

Room.prototype.onMouseClickHandler = function(event) { 
    // 'boxName' is undefined as 'this' references 'event.target' 
    console.log(window.boxName); 
} 
+1

不會window.boxName干擾其他Box實例嗎?並且在您的評論中,您說使用box_instance_key - 但是如何從實例中獲取實例密鑰? – user1960364

+0

@ user1960364是的,這就是爲什麼我向頂部添加註釋,說您可以使用某種實例ID來分隔它們。我用評論更新了代碼。 –

+0

對不起,原型應該是Box.prototype ...更新了問題。 因此,我仍然不確定如何從原型中獲取boxData.id。 – user1960364

2

對於您的畫布使用Box實例作爲上下文,您需要綁定它。

你可以嘗試這樣的事情:

function Box(boxData) { 
    // References the Box instance as I want. 
    console.log(this); 

    // I need to access this later... 
    var boxName = boxData.name; 

    // public property boxName 
    this.boxName = boxName; 

    var $canvas = $('#rm-' + boxData.id).find('canvas'); 
    $canvas.on('mousedown', this.onMouseDownHandler.bind(this)); 
    // ----------------------------------------------^ 
    // this bind will prevent the event use canvas element as context 
} 

function Room() { 
    // some stuff 
} 

Room.prototype = new Box({name: 'this will always be my rooms box'}); 

Room.prototype.onMouseClickHandler = function(event) { 
    // 'boxName' is undefined as 'this' references 'event.target' 
    console.log(this.boxName); 
} 

現在你可以試試這個:

var foo = new Room(); 
foo.onMouseClickHandler(); 

而且您的控制檯將記錄this will always be my rooms box

你記住,房間擴展盒的一個實例,因此,如果你這樣做:

foo.boxName = 'my name is what?!'; 

// you changed the this so the prototype will get the new value: 
foo.onMouseClickHandler(); // 'my name is what?!' 

EDIT(問題升級後)

只需使用this.boxName代替var boxName

function Box(boxData) { 
    // References the Box instance as I want. 
    console.log(this); 

    // public property boxName 
    this.boxName = boxName; 
} 

如果你想爲其他對象添加一個EventHandler,但保留你的Box控件文本你需要這樣做:

var foo = newBox({boxName: 'foo'}); 
var bar = document.queryElementById('bar'); 

bar.addEventHandler('click', foo.onMouseClickHandler.bind(foo)); 

現在,如果你在bar元素,從富的onMouseClickHandler點擊,將保持它的上下文。點擊事件將通過拋出參數。

+0

對不起,我更新了最初的問題。原型和構造函數都應該說Box ... – user1960364

+0

@ user1960364好的,答案也更新了。 –

+0

問題是,'this'在事件處理程序中使用時沒有引用Box對象實例。 – user1960364

0

實際上你有兩個問題。

可變範圍在JS

變量始終具有功能範圍。構造函數中的局部變量將保留在構造函數的本地變量中,並且不能在外部使用。

創建爲每個對象

不能行動中使用全局變量作爲一個單身

全局,靜態變量似乎是你想的正好相反。我想你的意思是public對象屬性而不是global變量。因此,使用一個:

function Box(boxData) { 
    // References the Box instance as I want. 
    console.log(this); 

    // create a property to be accessed later... 
    this.boxName = boxData.name; 
} 

'boxName' 未定義 '本次' 引用 'event.target'

是,該功能的情況下取決於(只)在它的調用。您將需要使用

var that = this; 
….addEventLister(…, function(event) { 
     that.onMouseClick(); // "that" references the instance 
}); 

註冊事件。

+0

你也可以綁定上下文,所以調用不會觸及它。 –