假设我正在制作一个JS库,该库具有一些用于DOM操作的函数。我有一些添加到元素中的函数,例如myElement.empty();
。我希望NodeList
s(例如从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.callee
和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
(和eval
(,但我想使用一些标准的、被认为可以使用的东西。
我该怎么做?
如果你需要更多信息,请在评论中询问,我会尽快回复。
不要使用那种奇怪的迭代风格,而是使用一个惯用的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
属性上,只需通过闭包访问即可。