Search code examples
javascriptarraysprototype

JS Prototype methods act differently while accessing in a loop


I am extending the array object with a new method called custommethod as follows and looping through the values inside an array. However, the looping through the indices also prints the name of the property which is extended via Array.prototype.<method>.

Array.prototype.custommethod = function() {
    console.log("Hello from Custom Method");
}

Object.defineProperty(Array.prototype, "anothercustommethod", {
    value: function() {
        console.log("Hello from Another Custom Method");
    }
});

Loop through the array

> x = [1,2]
[ 1, 2 ]

> for (i in x) { console.log(i); }
0
1
custommethod
  • Why doesn't the anothercustommethod get printed in this loop?

  • Is using the Object.defineProperty() a safer way to create Array.prototype?

I am curious as to how the for loop in javascript actually works. Does it use Object.keys() internally? If so how does it print custommethod which is inside __proto__ property but not anothercustommethod which is also inside __proto__ property?


Solution

  • Why doesn't the anothercustommethod get printed in this loop?

    for in iterates over those properties, which data descriptor enumerable is set to true.

    In the Documentation

    enumerable true if and only if this property shows up during enumeration of the properties on the corresponding object. Defaults to false.

    When using defineProperty, you can also pass an extra property - enumerable. By default it is set to false.

    Array.prototype.custommethod = function() {
        console.log("Hello from Custom Method");
    }
    
    Object.defineProperty(Array.prototype, "anothercustommethod", {
        value: function() {
            console.log("Hello from Another Custom Method");
        },
        enumerable: true
    });
    
    const x = [1,2]
    for (i in x) { console.log(i); }

    Is using the Object.defineProperty() a safer way to create Array.prototype?

    There is nothing about safe. Try to change the build in prototypes rarely