'For In' can traverse Array (value/properties/function).
let arr = [1,2,3,4];
arr.__proto__.con = function(){console.log('from array');}
for(let item in arr){
console.log(item);
}
The result will be:
1,2,3,4,con
why does native function like 'toString'/'split' not be printed? what is the difference?
In my mind, they(con
and toString
) all belong to the prototype of Array.
The native prototype is a JavaScript property that all built-in constructor functions in JavaScript use to inherit methods and properties from one another.
The prototype property is set to function when it is declared. All the functions have a prototype property. proto property that is set to an object when it is created using a new keyword. All objects behavior newly created have proto properties.
What they are? Native methods are built-in functions provided by the ECMAScript core specification. So things like Object methods (e.g. Object. create ), Array methods (e.g. Array#forEach ) etc.
So what's the difference between constructor and prototype? A short answer is that the constructor is a function that is used to create an object, while the prototype is an object that contains properties and methods that are inherited by objects created from a constructor.
The for...in
statement...
iterates over all non-Symbol, enumerable properties of an object. (source: MDN)
However, if you look at the ECMA specification, in the item "Properties of the Array Prototype Object", you'll see that:
The Array prototype object is the intrinsic object %ArrayPrototype%. The Array prototype object is an Array exotic objects and has the internal methods specified for such objects. It has a length property whose initial value is 0 and whose attributes are { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }.
That applies to concat
, filter
, map
, forEach
, sort
, toString
etc...
You can use Object.getOwnPropertyDescriptor
to check those attributes. For instance:
console.log(Object.getOwnPropertyDescriptor(Array.prototype, "concat"));
Finally, for setting those methods with {enumerable: false}
, have a look at the other answer.
It doesn't matter that the method is assigned to the prototype. Properties of any type of object are enumerable by default, whether they are assigned to the object's prototype or directly to the object:
class MyClass {
constructor() {
this.x = 10;
}
}
let test = new MyClass();
test.y = 20;
for(let item in test) {console.log(item) } // logs x, y
Native methods like toString
are set to be non-enumerable, for the obvious reason that you don't often want to loop through them. User methods or properties can also be set to be non-enumerable, by using Object.defineProperty
:
Object.defineProperty(test, "z", {value: 42, enumerable: false})
console.log(test.z); // 42
for(let item in test) {console.log(item)} // still only x, y
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With