2

关于arguments.callee有很多谬误,我试图了解是否存在确实不能被可行的ES5 严格模式替代方案取代的用例。

MDN arguments.callee文档中,他们指出了 arguments.callee 的使用,没有很好的替代方法,下面的代码示例如下:

function createPerson (sIdentity) {
    var oPerson = new Function("alert(arguments.callee.identity);");
    oPerson.identity = sIdentity;
    return oPerson;
}

var john = createPerson("John Smith");

john();

他们包含一个错误,以表明在某些情况下,argument.callee不能被符合ES5 严格模式的代码替换。

但在理解上,他们用作示例的代码可以替换为以下严格模式替代方案:

"use strict";

function createPerson(sIdentity) {
    var oPerson = function () {
        alert(oPerson.identity);
    };

    oPerson.identity = sIdentity;
    return oPerson;
}

var john = createPerson("John Smith");

john();

有了这一点,确实存在一些无法替换 arguments.callee 的算法?

赏金

为了赢得赏金,我希望答案包含arguments.callee使用其他解决方案将更加晦涩或不可能的地方。

在 MDN 示例中,我编写的替代版本不会改变那段代码的用法。

4

3 回答 3

2

这是一个用例:为内联事件处理程序(可能来自生成/模板化的代码)保留一个变量,而不会污染全局命名空间或 DOM 或冒其他名称冲突的风险:

<button onclick="var f=arguments.callee;alert(f.i=(f.i||0)+1)">CLICK</button>

示范

现在,假设它不是合法用途。当然,没有真正合法的或arguments.callee不会被砍掉的。

于 2014-05-26T16:46:51.690 回答
0

恐怕你误解了这个例子。这意味着使用Function构造函数没有argument.callee的替代品也就是说,下面的代码

function createPerson (sIdentity) {
    var oPerson = new Function("alert(oPerson.identity);");
    oPerson.identity = sIdentity;
    return oPerson;
}

var john = createPerson("John Smith");

john();

是错的

于 2014-05-26T16:30:25.093 回答
0

当您动态地(从字符串)创建函数时,它不能像普通闭包那样“捕获”任何外部变量。

因此,MDN 示例通过使值可访问来模拟闭包arguments.callee。如果不更改函数的签名,确实没有其他方法。

于 2014-05-23T16:02:35.213 回答