In my journey to become stronger in JavaScript, I have taken up a challenge to add a method, myMethod()
, to the JavaScript Object class that can be called on a given Object, myObject
, in order to manipulate its contents.
I have gotten as far as adding myMethod()
to the Object prototype and traversing through myObject
via myObject.myMethod()
; however, I'm running into a curious problem: at the end of the given object, myMethod()
is printed as an value of myObject
even though, to my knowledge, it should not be.
Object.prototype.myMethod = function()
{
for (var key in this)
{
console.log(this[key]);
}
}
function processData(input)
{
//Enter your code here
var myObject = JSON.parse("{ \"myParam\": \"myValue\", \"anotherParam\": 123 }");
myObject.myMethod();
}
The following is the output of this code:
myValue
123
[Function]
Changing myObject[key]
to myObject[key].toString()
has the following output:
myValue
123
function ()
{
for (var key in this)
{
console.log(this[key].toString());
}
}
I am executing this script in WebStorm using a Node.js runtime.
The requirements of this challenge only calls for the contents of myObject
, and I can't figure out how to stop myMethod()
from showing up here. Is there something I'm missing?
In my journey to become stronger in JavaScript, I have taken up a challenge to add a method,
myMethod()
, to the JavaScriptObject
class that can be called on a givenObject
,myObject
, in order to manipulate its contents.
Beware that this practice is seriously frowned-upon (here in 2017, possibly more than it strictly necessary*). Extending any built-in prototype is a bit fraught, but extending Object.prototype
is particularly problematic since, of course, almost all objects inherit from it.
But if you're going to extend a prototype, it's important to add a non-enumerable property via Object.defineProperty
or similar:
Object.defineProperty(Object.prototype, "myMethod", {
value: function() { /* ... */ }
});
The default for enumerable
is false
, so it won't show up in for-in
loops, Object.keys
arrays, etc.
* The "don't extend built-in prototypes" mantra started before ES5's introduction of a way of defining non-enumerable properties (e.g., defineProperty
). Now that we can define non-enumerable properties, the chief concern is inter-script conflict, each trying to use the same name for something, or conflict with new features as they're added to JavaScript.