2014-03-01 131 views
1

這工作:如何在JavaScript對象內正確定義(函數||函數)?

<div id="result"></div> 

<script type="text/javascript"> 
var Base64Encode = window.btoa || CryptoJS.enc.Base64.stringify; 

document.getElementById('result').innerHTML = Base64Encode("Please work."); 
</script> 

然而,這樣的:

<div id="result"></div> 

<script type="text/javascript"> 
var Test = { 
    Base64Encode: window.btoa || CryptoJS.enc.Base64.stringify 
}; 

document.getElementById('result').innerHTML = Test.Base64Encode("Please work."); 
</script> 

生成的錯誤 「類型錯誤: 'BTOA' 調用的對象沒有實現界面窗口中點擊」

小提琴:

http://jsfiddle.net/kAGU2/

爲什麼第一個例子中的工作,但第二個發出的錯誤?什麼是解決這個特定錯誤的正確方法?

回答

5

Why does the first example work but the second one emit that error?

當函數被調用爲Base64Encode(),將this context被隱式設置爲window。但是,當您將其稱爲Test.Base64Encode()上的方法時,this將參考Testbtoa這方面的情況。

What's the correct way to fix this particular error?

您需要bind它預期的背景下:

Base64Encode = window.btoa 
    ? window.btoa.bind(window) 
    : CryptoJS.enc.Base64.stringify; 
+0

我喜歡的風格和解決方案的工作。謝謝! – CubicleSoft

0

使用.bind()

var Test = { 
    Base64Encode: function() { 
     if (window.btoa) 
     return window.btoa.bind(window); 

     return CryptoJS.enc.Base64.stringify; 
    }() 
}; 

你,因爲您是通過對象屬性引用調用的功能得到了錯誤。當你這樣做時,this的值被設置爲對涉及的對象的引用。 btoa()功能不喜歡那個(誰知道什麼原因),但.bind()爲您創建一個包裝功能,確保正確的this

0

看來作爲BTOA功能是窗口類的成員函數。因此必須使用此設置調用window

爲了它在你的安裝工作,你應該這樣調用它:

Test.Base64Encode.call(window,"Please work."); 
+0

每次你打電話時都不需要寫出來,尤其是在後備使用中,甚至完全沒有必要。在分配期間綁定它是一個更好的選擇。 –

+1

的確如此。但是我會從重新思考原始設計開始,如果出現這樣的問題,那麼在概念上是錯誤的。 –