6

我正在将一些旧代码移植到“严格模式”,在 ECMA5 标准中,argument.callee 和类似的 argument.caller 等的替代品是什么?


附加信息:我没有说明为什么我需要 argument.caller/callee。

我正在移植的代码正在使用

assert.ok(elemNode, arguments.callee.name + ": Entity - " + entityId + " has been found");

如果它是简单的递归,我可以使用函数名(){...函数()...},但我似乎无法找到如何处理上面的代码。

4

4 回答 4

7

从 ECMAScript 3 开始,您可以拥有命名函数表达式。在此之前,函数表达式是匿名的,这是arguments.callee必要的。命名函数表达式使其变得不必要。所以这是推荐的替代方案。

查看被调用者的 MDN 文档

例子:

[1,2,3,4,5].map(function factorial (n) {
    return !(n > 1) ? 1 : factorial(n-1)*n;
});

命名函数的好处(来自 MDN 文档):

  • 可以像从代码内部调用任何其他函数一样调用该函数
  • 它不会污染命名空间
  • this 的值不会改变
  • 它的性能更高(访问参数对象很昂贵)
于 2013-03-21T20:38:38.890 回答
3

并不真地。

没有办法模仿或“填充”该属性,出于安全原因arguments.caller已将其删除,因此您无法在代码中爬上作用域链。

最好的替代方法arguments.callee是只使用命名函数表达式,而不是匿名函数表达式,例如

setTimeout(function loop() {
    if( /* condition */ ) {
        loop();  // instead of arguments.callee();
    }
}, 1000);

这在几乎所有实现中也更快(访问arguments对象通常有点慢)

于 2013-03-21T20:38:13.393 回答
1

您需要命名您的函数,然后只需按该名称引用该函数。

于 2013-03-21T20:36:37.877 回答
0

严格来说,没有等价物。正如 John Resig指出的那样,您需要在 ECMAScript 5 的严格模式下命名您的“匿名”函数,然后您可以直接调用它们。他的例子是:

setTimeout(function later(){
  // do stuff...
  setTimeout( later, 1000 );
}, 1000 );
于 2013-03-21T20:41:30.163 回答