开发者

Javascript object construction: whats the difference?

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 f开发者_开发问答irst 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


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


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.


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜