Summary of defects in Javascript for in

  • 2021-07-16 01:17:03
  • OfStack

Summary of defects in Javascript for in

The for in statement is used to enumerate the properties (members) of an object, as follows


var obj = { name:"jack",
   getName:function(){return this.name}
};
// Output name,getName  
for(var atr in obj) {
  alert(atr);
}

Notice that toString, valueOf and other built-in properties (or built-in members, hidden properties, and predefined properties) of obj are not output. That is, for in is used to enumerate display members (custom members) of objects.

If you override the built-in properties, then override the toString of obj


var obj = {name:"jack",
   getName:function(){return this.name},
   toString:function(){return "I'm jack."}
}
for(var atr in obj) {
  alert(atr);
}

What will it output?

1. Under IE6/7/8 and without rewriting toString1, only name and getName are still output

2. name, getName and toString are output under IE9/Firefox/Chrome/Opera/Safari

If you add properties/methods to the built-in prototype, then for in is also traversible


Object.prototype.clone = function() {}
var obj = {
  name: 'jack',
  age: 33
}
// name, age, clone
for (var n in obj) {
  alert(n)
}

The method clone is added to Object. prototype, and clone is displayed in all browsers when for in.

This is probably nothing, since it is generally not recommended to extend the prototype of the built-in constructor, which is one of the reasons why Prototype. js is in decline. jQuery and Underscore do not extend self-prototypes. The former makes a fuss about jQuery objects, while the latter simply hangs all methods on underscores.

But sometimes we extend the prototype of the built-in constructor on browsers that do not support ES5 (IE6/7/8) to be compatible with ES5 or later versions, so for in is different from browser to browser. As follows


if (!Function.prototype.bind) {
  Function.prototype.bind = function(scope) {
    var fn = this
    return function () {
      fn.apply(scope, arguments)
    }
  }
}
function greet(name) { 
  alert(this.greet + ', ' + name)
}
for (var n in greet) {
  alert(n)
}

IE6/7/8 outputs bind, other browsers do not. Because bind is natively supported in modern browsers, for in is less than IE6/7/8 adds bind to Function. prototype.

To sum up: In cross-browser design, we can't rely on for in to get the member names of objects, but use hasOwnProperty to judge.

Thank you for reading, hope to help everyone, thank you for your support to this site!


Related articles: