2

Say I have the following Function

function FooController (){
  this.foo = function () {
    alert('foo');
  }
}

FooController.prototype.bar = function () {
  alert('bar');
}

Is there a difference between these two syntaxes? Why would I use one over the other? Is there a performance hit?

Abraham P
  • 15,029
  • 13
  • 58
  • 126
  • 1
    this just has to be a duplicate... – Alnitak Oct 09 '14 at 21:43
  • 1. yes, there's a diff, but it might be invisible depending on how you use instances. 2. it's complicated, know your options. 3. no, these days engines recycle function objects internally anyway, so the perf diff is minimal. – dandavis Oct 09 '14 at 21:50
  • all instances of object X will have the function you defined under the prototype. – Ryan Oct 09 '14 at 21:52

2 Answers2

1

If it's defined on the prototype, any instance of FooController will "inherit" the bar method because it's in the instance's prototype chain. Only 1 function is defined and in memory using this technique.

If you define using this.foo = function, you're adding the function directly to the instance as a property of that instance. This means that you will have 1 function in memory per instance of the controller.

function FooController {}

FooController.prototype.hello = function() {
  console.log("world");
};

Create an instance and check the prototype's value

var c = new FooController();
c.hello(); // "world"

This is as expected, but let's define a hello method directly on the c instance

c.hello = function() { console.log("cats"); };
c.hello(); // "cats"

We can still call the prototype method directly

c.prototype.hello.call(c); // "world"

Or we can delete the hello property on the c instance

delete c.hello;

Now let's call our function again

c.hello; // "world"

It's back to using the prototype's method !

Mulan
  • 129,518
  • 31
  • 228
  • 259
  • these days engines recycle function objects internally, which the ES3 spec allows, so having "1 function in memory per instance" is not always the case like it would be with C or something like that. – dandavis Oct 09 '14 at 21:52
1

All instances of FooController will share bar, each foo will be created individually per object.

In general you want properties to be created with the this. syntax, so they're not shared, and functions to be created using the prototype syntax (there's no point in many identical functions)

You can run into trouble if you put functions on the prototypes. With primitives you won't notice the difference, since writing to them will write to the local object and ignore the protoype, but you can cause problems with arrays like this.

function FooController (){
  this.foo = function () {
    alert('foo');
  }
}

FooController.prototype.bar = [];

var a = new FooController();
var b = new FooController();

a.bar.push['hi'];

alert(b.bar.length); //1
Ben McCormick
  • 25,260
  • 12
  • 52
  • 71
  • another highly significant advantage of the `this.foo = ` method is that `foo` then has access to the "private" lexically scoped variables inside `FooController`. A prototype method cannot do that. – Alnitak Oct 09 '14 at 21:46
  • true. I stopped writing when the question got closed :) – Ben McCormick Oct 09 '14 at 22:00