首页 > 解决方案 > 当我需要访问变量时,如何不使用 arguments.callee?

问题描述

假设我正在制作一个 JS 库,其中包含一些用于 DOM 操作的功能。我有一些添加到元素的函数,例如myElement.empty();. 我希望NodeLists 具有相同的功能(例如,从返回的对象querySelectorAll)。要动态添加功能,我已经完成了以下操作(请注意,以下操作确实有效):

var funcs=["text","html","attr","remove","empty","css"];
var n=funcs.length;
while(~--n){
    var f=function(){
        var i,l=this.length;
        for(i=0;i<l;i++){
            this[i][ funcs[arguments.callee.n] ].apply(this[i], arguments);
        }
        return this;
    };
    f.n=n;
    NodeList.prototype[funcs[n]]=f;
}

这行得通,但我听说这arguments.callee 在“严格”模式下不起作用

有人说要给函数起个名字,但我不能,虽然我试过:

var funcs=["text","html","attr","remove","empty","css"];
var n=funcs.length;
while(~--n){
    this[funcs[n]]=function(){
        var i,l=this.length;
        for(i=0;i<l;i++){
            this[i][ funcs[name] ].apply(this[i], arguments);
            // In the above it has 'name' which references the function name
        }
        return this;
    };
    NodeList.prototype[funcs[n]]=this[funcs[n]];
}

那没有用。 我能够使用eval. 我决定不使用eval,尽管它有效(通过放入n字符串并从中制作函数)。如果我不得不使用其中一个,我认为这arguments.callee可能比 更好。eval

如何在不使用建议的任何内容(例如arguments.calleeand eval)的情况下使我的功能正常工作?

编辑以获取更多详细信息:

假设我定义了一个empty函数(再次出于问题的目的,我们假设修改原型是可以的):

Element.prototype.empty=function(){
    while(this.childNodes[0])
        this.childNodes[0].remove();
};

这适用于一个元素。如果用户想做类似的事情怎么办:

document.querySelectorAll("button .myclass").empty();

所以我想制作一个脚本,NodeLists为每个元素调用相应的函数动态创建函数,例如:

NodeList.prototype.empty=function(){
    var i,l=this.length;
    for(i=0;i<l;i++)
        this[i].empty();
    return this;
};

如果我想执行上述操作,我将需要创建许多功能非常相似的功能。所以我想写一些代码来动态地为NodeList. 正如您可能在上面所读到的,我使用arguments.callee(and eval) 进行了操作,但我想使用标准的并且认为可以使用的东西。

我该怎么做?

如果您需要更多信息,请在评论中提问,我会尽快回复。

标签: javascripteval

解决方案


不要使用那种奇怪的迭代风格,而是for … of允许使用块范围变量的惯用循环:

const funcNames = ["text","html","attr","remove","empty","css"];
for (const name of funcNames) {
    NodeList.prototype[name] = function(...args) {
        for (let i=0; i<this.length; i++) {
            this[i][name](...args);
        }
        return this;
    };
}

没有理由访问当前函数或将名称存储在其.n属性中,只需通过闭包访问它即可。


推荐阅读