0

Here it says:

Place instance variable declaration/initialization on the prototype for instance variables with value type (rather than reference type) initialization values (i.e. values of type number, Boolean, null, undefined, or string). This avoids unnecessarily running the initialization code each time the constructor is called. (This can't be done for instance variables whose initial value is dependent on arguments to the constructor, or some other state at time of construction.)

And it gives the following example, instead of:

foo.Bar = function() {
  this.prop1_ = 4;
  this.prop2_ = true;
  this.prop3_ = [];
  this.prop4_ = 'blah';
};

Use:

foo.Bar = function() {
  this.prop3_ = [];
};

foo.Bar.prototype.prop1_ = 4;
foo.Bar.prototype.prop2_ = true;
foo.Bar.prototype.prop4_ = 'blah';

Now, I create two instances of the foo.Bar w.r.t. the second scenario:

foo = {}
f1 = new foo.Bar()
f2 = new foo.Bar()

And then test:

f1.prop1_ // gives 4
f1.prop1_ = 5 // changed it
f2.prop1_ // still gives 4
Object.getPrototypeOf(f1) === Object.getPrototypeOf(f2) // true

Now my question: although f1 and f2 share the same prototype, each one's prototype seem to have different scopes (enclosures?), thus, they have their own copies of the prop1_; which means separate memory allocations taking place. Why is this a performance gain?

2 Answers 2

1

It is more efficient because you're not running a bunch of assignment code within the constructor, that much should be obvious. It is sharing the same values on the prototype, as anything is shared on the prototype.

The thing is, when you read the value f1.prop1_, it looks up the value from the prototype chain since f1 itself doesn't have the property prop1_. But, when you assign to the property with f1.prop1_ = 5, it assigns directly to a property on the f1 object. In other words, assignment creates the property on the object itself. The prototype value is henceforth shadowed by the instance property. That's why instances will have separate values.

This is fine for immutable values; it's a bad idea for mutable values like arrays, since f1.arr_.push(foo) would mutate the object on the prototype instead of creating a property on the individual instance.

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

1 Comment

i have read that somewhere, but had to experience it myself I guess ;)
1

No. if you create two instances, the whole prototype chain would look like this:

 foo.Bar.prototype {
   prop1_ :4
 }
f1{
  proto:foo.Bar.prototype
 }
 f2{
  proto:foo.Bar.prototype
 }

so when you do

f1.prop1_

it checks if the property exists in f1 (which it doesnt) , then it looks it up in the prototype, and evaluates to 4.

If you do

f1.prop1_ = 1;

it doesnt set the property of the prototype, but of the element itself:

foo.Bar.prototype {
   prop1_ :4
 }
f1{
  proto:foo.Bar.prototype
  prop1_:1
 }
 f2{
  proto:foo.Bar.prototype
 }

So the results:

f1.prop1_ // 1
f2.prop2_ // 4 (looked up in prototype)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.