简体   繁体   中英

Why this doesn't bind using forEach, but does bind using a for in loop?

I was attempting to make a function that sets multiple attributes to an HTML element. I used the code provided by a Stack Overflow user on this page

Setting multiple attributes for an element at once with JavaScript

If I use a for in loop, the binding of this is successful, but if I use a forEach it is not? Why is that?

This Works

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]);
    }
  }
}

This does not work

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]);
      }
  });
}

However if I don't modify the Element Object and just make a regular function with the ForEach loop it works just fine.

Simple Implementation

var myDiv = document.getElementById("myDiv");

myDiv.attributeSetter({
    class: "coolDiv",
  style: {
    color: "#0110ff",
    border: "2px solid lime"
  },
  "data-order": "one",
  "html": "Cool Div"
}); 

The second snippet with foreach does not work because inside foreach this does not point to the div but to the window object and that is why you are getting error this.setAttribute is not a function

Change the implementation like below.

 Element.prototype.attributeSetter = function(attrs){ var elem = this; Object.keys(attrs).forEach(function(prop){ if((prop == "style" || prop == "styles") && (typeof attrs[prop] === 'object')){ for(var n in attrs[prop]){ elem.style[n] = attrs[prop][n]; } }else if(prop == "html"){ elem.innerHTML = attrs[prop]; }else{ //TypeError: this.setAttribute is not a function elem.setAttribute(prop, attrs[prop]); } }); } var myDiv = document.getElementById("myDiv"); myDiv.attributeSetter({ class: "coolDiv", style: { color: "#0110ff", border: "2px solid lime" }, "data-order": "one", "html": "Cool Div" }); 
  <div id="myDiv"></div> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM