2016-01-21 51 views
2

對於prototype方法,是否存在確保this永遠是對象本身(在檢查instanceof並拋出錯誤之外)的安全方法。確保原型方法內的「this」上下文

var Dialog = function() {}; 
Dialog.prototype.open = function() { 
    var open = this; 
    // how do ensure "this" is always the Dialog 
    console.log(open); 
}; 

使用此代碼,任何用戶都可能錯誤地「脅迫」上下文不正確。例如:

var pointer = new Dialog().open; 
pointer(); // "this" would become Window 

我試圖找到一種方式來處理這個內部這樣我就不必拋出異常或依靠用戶總是做正確的事。

用戶總是可以打電話給pointer.call(dialog),但這意味着他們需要一個單獨的對話框指針,這是對用戶而不是作者,作者負擔的一個好例子。

+1

你打算有Dialog'的'多個實例?你想讓用戶直接使用'Dialog'的實例嗎? ('變種d =新的對話框(); d.open();') –

+2

這是不是你的類/庫真正應該擔心。如果用戶錯誤地調用/調用方法,那是他們的問題。他們應該正確使用正確的語言才能正常工作。 –

+0

是的,可能有多個實例,我將允許用戶重複使用一個實例。 – helion3

回答

1

這簡直瘋了,善良的廢墟的性能提升您的原型繼承獲得,但你可以明確地綁定在構造函數中的每一個功能。

function log(obj) { 
 
    document.querySelector('pre').innerText += obj.toString() + '\n'; 
 
} 
 

 
function Dialog() { 
 
    this.open = this.open.bind(this); 
 
} 
 
Dialog.prototype.open = function() { 
 
    log(this); 
 
}; 
 
Dialog.prototype.toString = function() { 
 
    return '[object Dialog]'; 
 
}; 
 

 
var d = new Dialog(); 
 
d.open(); 
 
var open = d.open; 
 
open();
<pre></pre>

這將創造的Dialog每個實例的每個方法的獨特功能,對象,但在技術上按照預期它會工作。

1

你真的不能防止這種使用原型。該bind建議由MikeÇ確實做的契稅,但它基本上是一個非常複雜/昂貴的方式使用Decorator模式,它確實解決作用域問題:

function Dialog() { 
    var dialog = this; 

    dialog.open = function() { 
     console.log(dialog, this); 
    }; 
} 

var d = new Dialog(); 
d.open(); 

var open = d.open(); 
open(); 

請記住,這種做法是非常內存效率低於您的問題中的prototype示例,因此如果您有很多實例,請不要使用它。

相關問題