'caller'和'arguments'是受限制的函数属性,在此上下文中无法访问

时间:2015-08-10 13:43:28

标签: javascript ecmascript-6 strict

我正在尝试创建一个简单的调试函数,它只显示一个函数的调用者,如下所示:

function xe() {
  console.log(xe.caller().name)
}

有了这个,我就可以将xe()添加到一个函数中,它会记录对函数的调用 - 只是一个简单的简单添加,以帮助调试。调试糖,可以这么说。

不幸的是,我从主题行中得到错误:

  

TypeError:'caller'和'arguments'是受限制的函数属性,在此上下文中无法访问。

我正在使用Babel / ES6,它在每个模块的顶部注入"use strict"。这个可能是的原因,但搜索已经提供了有关错误引发原因的有限信息,我想更好地理解它。

如果严格模式是问题,我宁愿不为整个项目禁用严格模式 - 只为模块/功能。

2 个答案:

答案 0 :(得分:22)

这是原因。 From MDN

  

在严格模式下,不再可能通过常规实现的ECMAScript扩展来“遍历”JavaScript堆栈。在具有这些扩展的普通代码中,当函数fun被调用时,fun.caller是最近称为fun的函数,fun.arguments是调用fun的参数。这两个扩展对于“安全”JavaScript都是有问题的,因为它们允许“安全”代码访问“特权”函数及其(可能是不安全的)参数。如果fun在严格模式下,fun.caller和fun.arguments都是不可删除的属性,在设置或检索时抛出:

如果您正在使用ES6,则无法在一般情况下禁用严格模式。它隐含在certain conditions期间,例如在ES6模块中。

如果您只是调试,我建议只在调试器中使用断点并检查堆栈帧,但我相信您已经知道了。

如果您只是输出调试信息,我想也可以读取Error对象的堆栈:

console.log(new Error().stack);

你可以globaly disable(但我意识到这不是你想要的)use strict与babel一起使用:

require("6to5").transform("code", { blacklist: ["useStrict"] });

$ 6to5 --blacklist useStrict

如果你必须在模块级别将其剥离,我怀疑你必须自己做。基本字符串替换可能吗?

此外,正如ES5中所指出的那样。它应该是xe.caller.name而不是xe.caller().name,否则您将重新调用该函数。

答案 1 :(得分:1)

根据this文档。 Function.caller()属性返回调用指定函数的函数。使用xe.caller时,您将获得完整的调用函数。你再次执行调用函数。在这里你正在做递归,这就是它不允许在严格模式下的原因。

您可以在浏览器控制台中执行示例功能。您将收到Maximum call stack size exceeded错误。