2014-03-01 89 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

的确如此。但是我会从重新思考原始设计开始,如果出现这样的问题,那么在概念上是错误的。 –