By Richard Keller


2013-07-04 15:59:08 8 Comments

What are the functional differences between the following two Javascript prototypes, and are there any benefits for choosing one over the other?

Option 1:

Person.prototype.sayName = function(name) {
   alert(name);
}

Option 2:

Person.prototype = {
   sayName: function(name) {
      alert(name);
   }
}

Am I correct in assuming that Option 2 results in trashing certain functions that are implicitly bound to the prototype?

5 comments

@Bergi 2013-07-04 16:46:54

Am I correct in assuming that Option 2 results in trashing certain functions that are implicitly bound to the prototype?

Yes, exactly. Though the only implicitly bound property is the constructor property, which you seldom do need.

What are the functional differences?

Option 1 is just extending the existing prototype. If there are already Person instances inheriting from the prototype object, they will be able to use the sayName method as well. With option 2, the new prototype will only be used for objects that are instantiated after the overwriting.

Are there any benefits for choosing one over the other?

These should be self-explaining now. Option 1 (extending) is considered cleaner, and is a must if you're modifying foreign/unknown/native prototypes. Try to avoid option 2.

If you still like the object literal syntax better, you should consider using Object.assign to extend the existing prototype:

Object.assign(Person.prototype, {
   sayName: function(name) {
      alert(name);
   }
});

You may need to polyfill Object.assign for pre-ES6 environments. Alternatively, $.extend or _.extend work just as well. Surely also your favourite library comes with a helper function for this.

@Alexander Mills 2015-05-24 16:18:04

why on earth should option 1 be considered cleaner. it appears to be that option 2 is the way to start with a clean slate so to speak.

@Bergi 2015-05-24 16:22:38

@AlexMills: Because you don't need to know what properties do already exist on the prototype that you'd otherwise overwrite, and will not break them (regardless where the code is called). It's simpler, less error-prone and forwards-compatible. Of course, if you create a prototype object from scratch, you may as well use the object literal, but even then most people forget the standard constructor property.

@Esailija 2013-07-04 17:10:56

Any existing instances of the constructor will continue pointing to the old prototype object. Any new instances created will point to the new prototype object.


The advantages of option 1 over option 2 are simply that you don't have to re-establish constructor property and you save one indentation level which is huge for me.

To save repetition, I just assign the property to a local variable:

var method = Person.prototype;

method.getAge = function() {
    return this.age;
};

method.getName = function() {
    return this.name;
};

Also common choices are fn (jQuery) and p which are even shorter than method.

@ebram khalil 2013-07-04 16:39:36

in simple words the difference is in Person.prototype.sayName all you do is to add a function to the prototype. just adding new functionality.

In the second Person.prototype = {} here you are making a new whole object and assign it to prototype. So you creating new object or overwrite the prototype with a new object.

First method is good to add many functions as you want on demand. You can add them each one on time, so i think it good when your program is simple and your application objects dose not share much functions or objects among them.

Second method is good if your application objects share some objects(or group of functions as @isaach said in Math functions) among them.

@HMR 2013-07-04 16:15:56

The second one will overwrite person.prototype with the object.

Method one:

Object.toString=function(){
  return "Object to string";
}
var Person = function(){
};
Person.toString=function(){
  return "Person to string";
}
Person.prototype.sayName=function(){}
console.log(Person.prototype.constructor.toString());// "Person to string"

Method two:

Object.toString=function(){
  return "Object to string";
}
var Person = function(){
};
Person.toString=function(){
  return "Person to string";
}
Person.prototype = {
  sayName:function(){}
}
console.log(Person.prototype.constructor.toString());// "Object to string"

@isaach1000 2013-07-04 16:04:23

The first is good for one or two extra functions, but defining a totally new prototype with many functions would be very repetitive. On the other hand, doing the latter would destroy all the existing definitions for the prototype as you mentioned.

In practice, I have used the first to define additional functions in Array and Math, etc., somewhat like categories in Objective-C. The latter I use as a "class definition."

@Richard Keller 2013-07-04 16:09:43

I understand that when adding onto an existing code library (like Math) you wouldn't want to completely trash the prototype, but when creating a new library from scratch, is there any reason why I shouldn't trash the prototype? In other words, when I'm creating a new prototype, does it have any functions attached to it already, or is it just a blank placeholder?

@HMR 2013-07-04 16:24:20

@RichardKeller You will overwrite the function's prototype with that of Object so you can't use new this.constructor() to create a new instance of this: phrogz.net/JS/classes/OOPinJS2.html

@isaach1000 2013-07-04 16:47:26

You are pretty safe with new prototypes. I tried experimenting in the Google Chrome console and I cannot destroy anything important. See this link.

Related Questions

Sponsored Content

89 Answered Questions

[SOLVED] How do I remove a particular element from an array in JavaScript?

  • 2011-04-23 22:17:18
  • Walker
  • 6166719 View
  • 7691 Score
  • 89 Answer
  • Tags:   javascript arrays

86 Answered Questions

[SOLVED] How do JavaScript closures work?

27 Answered Questions

[SOLVED] What does "use strict" do in JavaScript, and what is the reasoning behind it?

41 Answered Questions

[SOLVED] How do I remove a property from a JavaScript object?

58 Answered Questions

[SOLVED] How do I include a JavaScript file in another JavaScript file?

3 Answered Questions

38 Answered Questions

[SOLVED] var functionName = function() {} vs function functionName() {}

13 Answered Questions

[SOLVED] event.preventDefault() vs. return false

25 Answered Questions

[SOLVED] How does JavaScript .prototype work?

Sponsored Content