The for in statement is used to list the properties (members) of an object, as follows
Copy the code code as follows:
var obj = { name:"jack",
getName:function(){return this.name}
};
//Output name,getName
for(var atr in obj) {
alert(atr);
}
Did you notice that there is no built-in properties (or built-in members, hidden properties and predefined properties) such as toString and valueOf of obj. That is, for in is used to enumerate the displayed members (custom members) of the object.
If you override the built-in properties, then rewrite obj's toString below.
Copy the code code as follows:
var obj = {name:"jack",
getName:function(){return this.name},
toString:function(){return "I'm jack."}
}
for(var atr in obj) {
alert(atr);
}
What will be output?
1. Under IE6/7/8, it is the same as without rewriting toString, and still only outputs name and getName.
2. Under IE9/Firefox/Chrome/Opera/Safari, name, getName, toString is output
If you add properties/methods to the built-in prototype, it will also be traversable during for in
Copy the code code as follows:
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 all browsers display clone when for in.
This may not matter, because it is generally not recommended to extend the prototype of the built-in constructor, which is one of the reasons for the decline of Prototype.js. jQuery and Underscore do not extend the self-prototype. The former makes a fuss about the jQuery object, while the latter simply hangs all methods under underscore.
But sometimes, in order to be compatible with ES5 or subsequent versions, we will extend the prototype of the built-in constructor on browsers that do not support ES5 (IE6/7/8). In this case, for in will be different in each browser. as follows
Copy the code code 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, but other browsers do not. Because bind is natively supported in modern browsers, and for in is not available, IE6/7/8 adds bind to Function.prototype.
To summarize: In cross-browser design, we cannot rely on for in to obtain the member names of the object. We generally use hasOwnProperty to judge.