【发布时间】:2016-12-26 10:03:33
【问题描述】:
我试图创建一个为 HTML 元素设置多个属性的函数。我在此页面上使用了 Stack Overflow 用户提供的代码
Setting multiple attributes for an element at once with JavaScript
如果我使用for in 循环,this 的绑定是成功的,但如果我使用forEach 不是?这是为什么呢?
这可行
Element.prototype.attributeSetter = function(attrs){
for(var prop in attrs){
if((prop == "style" || prop == "styles") && (typeof attrs[prop] === 'object')){
for(var n in attrs[prop]){
this.style[n] = attrs[prop][n];
}
}else if(prop == "html"){
this.innerHTML = attrs[prop];
}else{
console.log("this: ", this);
this.setAttribute(prop, attrs[prop]);
}
}
}
这不起作用
Element.prototype.attributeSetter = function(attrs){
Object.keys(attrs).forEach(function(prop){
if((prop == "style" || prop == "styles") && (typeof attrs[prop] === 'object')){
for(var n in attrs[prop]){
this.style[n] = attrs[prop][n];
}
}else if(prop == "html"){
this.innerHTML = attrs[prop];
}else{
//TypeError: this.setAttribute is not a function
console.log("this: ", this);
this.setAttribute(prop, attrs[prop]);
}
});
}
但是,如果我不修改元素对象,而只是使用 ForEach 循环创建一个常规函数,它就可以正常工作。
简单实现
var myDiv = document.getElementById("myDiv");
myDiv.attributeSetter({
class: "coolDiv",
style: {
color: "#0110ff",
border: "2px solid lime"
},
"data-order": "one",
"html": "Cool Div"
});
【问题讨论】:
-
您是否尝试过将“这不起作用”示例的倒数第二行更改为 }.bind(this));
-
forEach 很垃圾而且很慢,所以.. 是的 :)。
-
@trevor 是的,这行得通,但我想知道为什么我必须这样做。对不起,如果这是一个糟糕的问题。
-
您必须这样做,因为您将回调函数传递给 .forEach()。您不知道回调何时执行,因此您使用 .bind(this) 创建回调函数的副本,该副本将在未来的时间在 myDiv 的上下文中执行。尽管@Deep 有一个有效的解决方案(称为“this”的词法捕获),但它并不是解决问题的最佳或最正确的方法。如果你想深入了解这些东西是如何工作的,我建议阅读 Kyle Simpson 的“你不知道 JS”系列书籍,在线免费:github.com/getify/You-Dont-Know-JS
-
@trevor 谢谢,很好的回答。
标签: javascript