Let’s take the example first:
// Poisoning Object.prototypeObject.prototype.bar = 1;var foo = {moo: 2};for(var i in foo) { console.log(i); // prints both bar and moo}We need to pay attention to two points here. One is that the for in loop will ignore the attribute set to enumerable to false. For example, the length property of an array. Second, since for in will traverse the entire prototype chain, when the prototype chain is too long, it will have an impact on performance.
enumerable is a very strange word. In fact, it is difficult for you to find its shadow in JavaScript, and it is actually borrowed from ruby by the author. The purpose of creating an enumerable is not to use it independently, but to use the "mixed" method. Many methods in Prototype use enumerable, so it can be said to be the cornerstone of prototype. I will not give a detailed introduction here, please refer to the details - Enumerable.
Since we cannot change the behavior of the for in loop itself, we can only take other methods to filter out properties that do not want to appear in the loop. Through "Javascript Learning Notes Objects (III): hasOwnProperty", we know that the hasOwnProperty method can do this.
Filter using hasOwnProperty
Still using the previous example:
// Poisoning Object.prototypeObject.prototype.bar = 1;var foo = {moo: 2}; for(var i in foo) { if (foo.hasOwnProperty(i)) { console.log(i); } }This is the only correct way to write it. Since we have used the hasOwnProperty method, we only output moo this time. If the hasOwnProperty method is not applicable, an error will appear when the Object.prototype is extended.
Now many frameworks choose to extend the method from Object.prototype, so when we use these frameworks, we will encounter problems if we use a for in loop that is not filtered with hasOwnProperty.
Summarize
It is recommended to develop the good habit of hasOwnProperty filtering properties, do not make any assumptions about the running environment, and whether the native prototype object is expanded or not.