0

I have this modified bit of code, from an online source, that discusses prototype inheritance.

var myObj = function() {}; // start w a regular func

myObj.prototype.a = 1; // attach properties to property
myObj.prototype.b = 2;

console.log('myObj dir a is: ' + myObj.a);  // undefined

var myRealObj = new myObj();
console.log('my real obj a is: ' + myRealObj.a); // works

My bit of confusion is the first log statement where a is undefined. Even though it's in the prototype chain above the function should it not walk the chain? Why does it work when I use new to create an object instead?

Thanks!

Siegmund Nagel
  • 1,321
  • 2
  • 11
  • 19
  • Why do you expect `myObj.prototype.a` to be the same thing as `myObj.a`? They’re not. The prototype works like this for instances, not for constructor functions. – Sebastian Simon Dec 19 '16 at 18:49
  • Don't confuse the `.prototype` property of constructors with their prototype chain. – Bergi Dec 19 '16 at 18:50

3 Answers3

1

Your confusion stems from the distinction between a "constructor function" and the object(s) that are created from that function (instances) when the new keyword is used.

In your first attempt to write to the console, you haven't actually invoked the constructor function:

// The "a" property won't exist because "myObj" isn't being invoked
console.log('myObj dir a is: ' + myObj.a);

Functions must be invoked with parenthesis and constructor functions must also be invoked with new in order to get a new object created from them.

So, in that first try you haven't received an object instance, so you get undefined. However, the prototype object does exist at that point, so if you had written:

console.log('myObj dir a is: ' + myObj.prototype.a);

You would have gotten the property value.

In your second attempt, you did use the constructor function to create an object instance. That new instance inherits from its specified prototype and so it gains the a and b properties of the prototype.

That invocation implicitly returns a reference to the new instance that was created and you are capturing that reference with your myRealObj variable.

Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
0

myObj.prototype is set as part of an instance's prototype chain ONLY when the new keyword is used. If the new keyword is not used, then there is no prototype chain relationship.

When the new keyword is used, you can imagine the following code is "injected" into a constructor function:

var myObj = function() {
  var this = Object.create(myObj.prototype); // which creates an empty object
                               // with myObj.prototype on its prototype chain

  // your code here...

  return this;
};
therobinkim
  • 2,500
  • 14
  • 20
0

Somewhat confusingly, myObj.prototype is not the prototype of myObj, it is the prototype that a new object created by using myObj as a constructor function would have.

myObj's prototype is myObj.__proto__

PMV
  • 2,058
  • 1
  • 10
  • 15