bar

Is it possible to define the prototype function of an Object in Javascript?

Object.prototype.doSomething = function(p) { this.innerHTML = "<em>bar</em>"; this.style.color = "#f00"; alert(p); }; document.getElementById("foo").doSomething("Hello World"); 

<div id="foo"><strong>foo</strong></div>

The code above works fine.

But I remember that I saw this somewhere: Do not mess with native Object. well, something like that.

Is it okay to define the prototype function in an Object ? Are there any reasons why I should not do this?

+7
source share
4 answers

The only safe way to add Object.prototype is to use the ES5 method Object.defineProperty to create an enumerable property:

 Object.defineProperty(Object.prototype, 'doSomething', { value: function(p) { ... }, enumerable: false, // actually the default }); 

This ensures that the new property does not appear if you execute for (key in object) .

Please note that this function cannot be reliably fixed, since there were no enumerable properties in previous versions of ECMAScript / JavaScript.

In any case, if your method applies only to elements of an HTML page, you better add it to Element.prototype instead of Object.prototype , although older (IE) browsers may complain if you do.

+5
source

This is usually not a good idea. This function is now available for everything that is in your application that uses the Object prototype (which is a lot) and will be displayed in the functions that enumerate the Object prototype.

The best option is to define a single prototype:

 function MyObject { ... } MyObject.prototype.doSomething = function() { ... } var myObj = new MyObject(); 
+1
source

If you add material to the prototype of an object, you lose the excellent functionality of iterating the object with for p in obj , since the added added properties are also repeated for all objects .

For example:

 Object.prototype.doSomething = function(p) { this.innerHTML = "<em>bar</em>"; this.style.color = "#f00"; alert(p); }; for (p in {foo:"bar"}){ console.log(p); } //foo //doSomething 

Unexpectedly, you will also get doSomething . To fix this, you will need to add a hasOwnproperty check when iterating over your object, but the risk here is that you can break other code that does not expect a simple object to have properties other than those specified in the literal.

+1
source

Another option is to call a method that is not defined as a prototype method of an object -

 function doSomething(p) { this.innerHTML = "<em>"+p+"</em>"; this.style.color = "#f00"; alert(p); }; 

//

 doSomething.call(document.getElementById("foo"),"Hello World"); 
0
source

All Articles