4

what's the difference in the construction of these two objects - apart from the privacy of the member variable ?

function A() { this.a = 99; } A.prototype.setA = function(newVal) { this.a = newVal; } A.prototype.getA = function({ return this.a; } 

And this:

function A() { var a = 99; return { setA: function(newVal) { a=newVal; } getA: function() { return a; } } } 

I'm not interested in the privacy of the member variable so much as the way the functions are defined.

Am I right in thinking that in the second version all objects created via new A() will get copies of the defined functions, where as in the first version all calls to the defined functions will go to the one and only prototype object (for the A object). Is this right?

If so does version 2 have any performance costs?

Also, Is one way preferred over another - or is there a better way again?

Many Thanks

4
  • Setters & getters are a horrible idea. Stop porting Java code to javascript. Commented Sep 20, 2011 at 17:07
  • @Raynos, not too horrible to be included in ES5. Commented Sep 20, 2011 at 17:14
  • @davin that's different. Those are native getter/setters (they are still evil). Emulated ones like setA and getA are beyond stupid. Native getter/setters should really only be used to do real clever stuff, not in every day code Commented Sep 20, 2011 at 17:16
  • @Raynos: Are you kidding me? JavaScript is keeping this industry two decades behind and people that promote these kind of comments are [CENSORED]! Commented Jun 25, 2012 at 15:10

4 Answers 4

6

Am I right in thinking that in the second version all objects created via new A() will get copies of the defined functions, where as in the first version all calls to the defined functions will go to the one and only prototype object (for the A object). Is this right?

Yes

If so does version 2 have any performance costs?

More memory usage with setA and getA per object A

Also, Is one way preferred over another - or is there a better way again?

Since you don't care about encapsulation, use prototype

Sign up to request clarification or add additional context in comments.

Comments

2

The first method defines those functions as properties of the A.prototype object which means that those functions are defined in one place for all instances of A.

The second method defines the functions (as properties) directly on the instance object, which means that you will have a new set of functions for every instance you create (= higher memory consumption).

The advantage of the first method is that you can shadow inherited methods if needed.

A.prototype.foo = function () { ... }; var a = new A; a.foo(); // inherited a.foo = function () { ... }; a.foo(); // shadowed delete a.foo; a.foo(); // back to inherited 

This can't be done like so when using the second method.

The advantage of the second method is that the functions capture the context of the constructor, so you can have private variables and functions in the constructor which then can be used by your functions.

This can't be done with functions defined on the prototype.


So my advice would be: If you need private variables or functions, use the second method. Otherwise, use the prototype.

1 Comment

+1 for summarizing the differences well and recommending when to use each.
1

The privacy of the inner variable aside, these should behave similarly, but you're correct, the second version will use more memory than the first. This is usually trivial unless you're working with large numbers of objects, but using the prototype approach there is only one getA and setA function, while with the second approach each has its own functions for these methods.

Comments

1

You're correct on both accounts.

So the performance difference would be memory consumption - the second way would consume more for each object. In addition, each object creation/instantiation might take slightly to longer in the second version because you have to create those memory-consuming functions, although this is negligible (in this toy case) and might even be offset by implementation-dependent factors.

I would recommend the prototypal method since for those reasons it scales slightly better. With regards to visibility even that can be pseudo-implemented in a prototypal manner with ES5.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.