2

Is there any difference between this:

function Foo(){
    this.bar = function(){
        console.log('hello');
    }
}
fooObj = new Foo();

and this?

function Foo(){

}

Foo.prototype.bar = function(){
    console.log('hello');
}
fooObj = new Foo();

These seem to behave the same, but I don't yet have a full understanding of prototypes. Is foo.prototype just a way of declaring a method outside of a class?

starscape
  • 2,739
  • 5
  • 26
  • 36

3 Answers3

7

The first example creates a new function object for each new object created with that constructor and assigns it to the property, the second example creates a single function that each new object references.

This means that for instance for your first example

var fooObj1 = new Foo();
var fooObj2 = new Foo();

alert(fooObj1.bar === fooObj2.bar) //false

while for the second

alert(fooObj1.bar === fooObj2.bar) //true

This is because in the first example the bar properties refer to 2 seperate but identical objects, while for the second they are the same.

In general the recommendation is that functions should be declared on the prototype to preserve memory, while other objects should be declared individually, unless you want to declare a "static" object that is shared among all objects created with that constructor.

Its easier to see the distinctions with normal objects or arrays rather than functions

function Foo(){
    this.bar = [];
}
var fooObj1 = new Foo();
var fooObj2 = new Foo();

fooObj1.bar.push("x");
alert(fooObj2.bar) //[]

as opposed to:

function Foo(){
}

Foo.prototype.bar = []
var fooObj1 = new Foo();
var fooObj2 = new Foo();

fooObj1.bar.push("x");
alert(fooObj2.bar) //["x"]
Ben McCormick
  • 25,260
  • 12
  • 52
  • 71
  • They are functionally the same, meaning they will both work the same way, but @ben336 is right; The prototype is used any time an object is created. The bad part of option 1 is that you have a separate copy of this method in every single object... it's less efficient. – Jess Mar 25 '13 at 17:19
3

basically, the difference is:

....
this.bar = function(){
        console.log('hello');
    }
....

means that each instance of Foo "class" will have its own bar.

....
Foo.prototype.bar = function(){
    console.log('hello');
}
....

means that all instances of Foo "class" will share one bar. Sort of static property.

Ruslan Polutsygan
  • 4,401
  • 2
  • 26
  • 37
-1

The bar method in the first example will not be inherited from Constructors that inherit from foo. Also, in the first example, objects created by foo will have their own unique copy of bar, while in the second example they share the same copy of bar.

When an object is created by a constructor, it gets a property called "proto" that points to the constructor's prototype property. "proto" is a special property in JavaScript that causes the object to inherit all of the properties of the prototype object it points to.

orb
  • 1,263
  • 1
  • 10
  • 16
  • proto is actually named two underscores + proto + two underscores. I guess I need to look up how to escape markdown . . . – orb Mar 25 '13 at 17:30