【问题标题】:Javascript named function expression, reference errorJavascript命名函数表达式,引用错误
【发布时间】:2014-08-29 19:23:33
【问题描述】:

我使用以下代码非常随机地(大约在 200 次尝试中出现一次)收到“参考错误”。

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 运行良好。

【问题讨论】:

  • 很可能Math.random 是您的问题,因为您“随机”收到错误。是否允许 Math.random 的所有值?
  • 如果是这样的话,我们会得到一个不同的错误。实际上这是可以替换的,因为我试图抽象函数。
  • 出现错误和没有出现错误的时间一定有所不同。将securityPrototype.encryptionKey.identifier 设置为固定值,看看是否仍然出现错误。
  • 好的,我已经测试了在 Windows 的 Chrome 中运行代码 500 次,我没有收到任何错误。这正是您收到错误时使用的代码吗?
  • @Guffa 几乎是相同的代码。不同之处在于 securityPrototype.encryptionKey.identifier 的值分配不同。主要问题是必须始终解决 encryptionKey 方法中的“x”引用。此功能与我收到的错误相同。

标签: node.js google-chrome javascript javascript-objects


【解决方案1】:

这是因为命名函数表达式的实现中存在一个错误,它存在于某些浏览器的某些版本中。

在这些浏览器中,当您使用命名函数表达式时,会创建两个单独的函数对象。属性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,您可以在其中阅读有关命名函数表达式和实现错误的更多信息。

【讨论】:

  • 此代码将给出引用错误,因为 'g' 未在 g 的定义范围之外定义。
  • var f = function g(){ console.log( g===f); }; f() // 返回真
  • @sbr:是的,在正确实现命名函数表达式的浏览器中,在函数外使用g应该给出引用错误。没有正确实现它的浏览器通常也存在标识符泄漏到函数范围之外的错误。请参阅我链接到的页面上的示例 #1。
  • 谢谢。那个链接很棒。虽然我想知道浏览器实现是否错误,但上面的代码总是会失败。
  • @sbr: 仅在某些浏览器的某些版本中实现错误。例如,旧版本的 IE 就有这些错误。
猜你喜欢
  • 2012-05-16
  • 2022-01-06
  • 1970-01-01
  • 2012-01-22
  • 1970-01-01
  • 2014-03-04
  • 2012-12-31
  • 2013-01-21
  • 1970-01-01
相关资源
最近更新 更多