Javascript命名函数表达式,参考错误
问题描述:
我使用以下代码非常随机地(大约一次在200次尝试中)收到“参考错误”。Javascript命名函数表达式,参考错误
var securityPrototype = {
init: function(){ /* ... */ },
encryptionKey: function x() {
var i = x.identifier;
return getKey(i);
}
}
securityPrototype.encryptionKey.identifier = Date.now();
function Security(){}
Security.prototype = securityPrototype;
Security.constructor = Security;
function getKey(){ /* ... */ }
var gate = new Security()
gate.encryptionKey(); // Randomly throws : ReferenceError: x is not defined
该代码段位于其他代码中,但没有使用“eval”,也没有使用'with'运算符。
我想弄清楚是否由于任何情况可能在这里得到这个错误。
重现此操作的浏览器:Mac和Windows上的Chrome。 IE和Safari工作正常。
答
这是因为存在于某些浏览器版本中的命名函数表达式的实现中的一个错误。
在这些浏览器中,使用命名函数表达式时会创建两个独立的函数对象。属性gate.encryptionKey
是对一个功能对象的引用,而名称x
是对不同的函数对象的引用。它们都包含相同的代码,但它们是Function
类的不同实例。
当您为gate.encryptionKey.identifier
赋值时,该属性仅在gate.encryptionKey
引用的函数对象中可用。 x
引用的函数对象不具有该属性。在这些浏览器的行为
简单的例子:
var f = function g(){};
f === g; // false
f.expando = 'foo';
g.expando; // undefined
这个例子(例如3#)从页Named function expressions demystified,在那里你可以阅读更多关于命名的函数表达式,并实现错误拍摄。
最有可能'Math.random'是你的问题,因为你得到的错误“随机”。是否允许'Math.random'的所有值? – Afsa 2014-08-29 19:30:25
如果是这样,我们会得到一个不同的错误。其实这是可以替代的,因为我试图抽象函数。 – sbr 2014-08-29 19:35:50
你得到错误的时间与没有的时间必须有所不同。将'securityPrototype.encryptionKey.identifier'设置为固定值,看看是否仍然出现错误。 – Afsa 2014-08-29 19:42:12