First example:
// Poisoning Object.prototype Object.prototype.bar = 1; var foo = {moo: 2}; for(var i in foo) { console.log(i); // prints both bar and moo }
We should pay attention to two points here. First, the for in loop will ignore the enumerable attribute set to false. For example, the length property of an array. The second is that since for in will traverse the entire prototype chain, when the prototype chain is too long, it will affect performance.
Enumerable is a very unfamiliar word. In fact, you can hardly find its shadow in JavaScript, and it is actually borrowed by the author from Ruby. The purpose of creating enumerable is not to use it independently, but to use it in a "mixed" way. Many methods in Prototype use enumerable mixedly, so it can be said to be the cornerstone of prototype. I won’t give a detailed introduction here. For details, please refer to - Enumerable.
Since we cannot change the behavior of the for in loop itself, we can only use other methods to filter out those properties that we do not want to appear in the loop. Through "Javascript Learning Notes - Objects (3): hasOwnProperty》We know that the hasOwnProperty method can do this.
Use hasOwnProperty filter
Still using the previous example:
// Poisoning Object.prototype Object.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, only moo is output this time. If the hasOwnProperty method is not applicable, an error will occur when Object.prototype is extended.
Many frameworks now choose to extend methods from Object.prototype, so when we use these frameworks, we will encounter problems if we use for in loops that are not filtered with hasOwnProperty.
Summary
It is recommended to develop a good habit of filtering properties with hasOwnProperty. Do not make any assumptions about the running environment, and regardless of whether the native prototype object is extended.