Rajesh Rajesh - 4 months ago 13
Javascript Question

Instance does not have access to prototype functions if parent function returns an object

I was testing something when I noticed that if you return object from a function, its instance will not have

custom prototype functions




// This works
function bar(){
var test = "test";
return test;
}

bar.prototype.notify = function(){console.log("Hello Bar");}
var b = new bar();
b.notify()

function bar1(){
var test = "test";
return {test: test};
}
bar1.prototype.notify = function(){console.log("Hello Bar");}
var b1 = new bar1();
b1.notify()





Note: Javascript Prototype not Working is a similar post but I'm looking for reason why it is not accessible.

Answer

The problem is that function has prototypes and objects has protos. In the second case you have an object, so there isn't any prototype.

In the first case, you make use of the constructor pattern. So the this is bound to the new object you create,

var b = new bar();

That being said, since the constructor's prototype contains a function called notify, this function is accessible from every object is created like above. (as a side node keep in mind that it's a convention the first letter of a constructor function, a function that is used only for creating new object using the new operator, to be capital. This way a constructor function is distinguished from the rest functions.)

On the other hand, in the following case:

function bar1(){
    var test = "test";
    return {test: test}; 
}

the return statement overrides the default behavior and it returns a new object.

As it is described in MDN:

When the code new Foo(...) is executed, the following things happen:

  1. A new object is created, inheriting from Foo.prototype.
  2. The constructor function Foo is called with the specified arguments, and with this bound to the newly created object. new Foo is equivalent to new Foo(), i.e. if no argument list is specified, Foo is called without arguments.
  3. The object returned by the constructor function becomes the result of the whole new expression. If the constructor function doesn't explicitly return an object, the object created in step 1 is used instead. (Normally constructors don't return a value, but they can choose to do so if they want to override the normal object creation process.)

// This works
function bar(){
  var test = "test";
  return test; 
}

bar.prototype.notify = function(){console.log("Hello Bar");}
var b = new bar();
document.write('b constructor is:'+ b.constructor);
document.write('</br>')

function bar1(){
  var test = "test";
  return {test: test}; 
}

var b1 = new bar1();
document.write('b1 constructor is:'+ b1.constructor);