Why constructor of A object is executed even though we change it manually to another constructor while...












1















function Animal() { console.log("Animal")}
function Bird() { console.log("Bird")}
function Dog() { console.log("Dog")}

Bird.prototype = Object.create(Animal.prototype);
Dog.prototype = Object.create(Animal.prototype);


duck = new Bird();
beagle = new Dog();


In the above code - we inherit Bird and Dog from Animal.
Their prototype will be animal. So by Default Bird.constructor will be pointing to Animal constructor.



When new Bird() is executed. I expect "Animal to be logged on console" but Bird is logged. Since the constructor is Animal. Animal constructor should be executed right? Correct my understanding










share|improve this question


















  • 1





    your assertions are not correct.

    – Pointy
    Nov 25 '18 at 17:30











  • Can you tell me the reasons @Pointy

    – Tharun26
    Nov 25 '18 at 17:31













  • yes working on it :)

    – Pointy
    Nov 25 '18 at 17:32











  • prototype and constructor are different things.

    – trincot
    Nov 25 '18 at 17:34






  • 1





    "When new Bird() is executed I expect "Animal" to be logged on console" - Why? Bird is defined as function Bird() { console.log("Bird") } so that's what you get when calling it.

    – Bergi
    Nov 25 '18 at 17:39


















1















function Animal() { console.log("Animal")}
function Bird() { console.log("Bird")}
function Dog() { console.log("Dog")}

Bird.prototype = Object.create(Animal.prototype);
Dog.prototype = Object.create(Animal.prototype);


duck = new Bird();
beagle = new Dog();


In the above code - we inherit Bird and Dog from Animal.
Their prototype will be animal. So by Default Bird.constructor will be pointing to Animal constructor.



When new Bird() is executed. I expect "Animal to be logged on console" but Bird is logged. Since the constructor is Animal. Animal constructor should be executed right? Correct my understanding










share|improve this question


















  • 1





    your assertions are not correct.

    – Pointy
    Nov 25 '18 at 17:30











  • Can you tell me the reasons @Pointy

    – Tharun26
    Nov 25 '18 at 17:31













  • yes working on it :)

    – Pointy
    Nov 25 '18 at 17:32











  • prototype and constructor are different things.

    – trincot
    Nov 25 '18 at 17:34






  • 1





    "When new Bird() is executed I expect "Animal" to be logged on console" - Why? Bird is defined as function Bird() { console.log("Bird") } so that's what you get when calling it.

    – Bergi
    Nov 25 '18 at 17:39
















1












1








1








function Animal() { console.log("Animal")}
function Bird() { console.log("Bird")}
function Dog() { console.log("Dog")}

Bird.prototype = Object.create(Animal.prototype);
Dog.prototype = Object.create(Animal.prototype);


duck = new Bird();
beagle = new Dog();


In the above code - we inherit Bird and Dog from Animal.
Their prototype will be animal. So by Default Bird.constructor will be pointing to Animal constructor.



When new Bird() is executed. I expect "Animal to be logged on console" but Bird is logged. Since the constructor is Animal. Animal constructor should be executed right? Correct my understanding










share|improve this question














function Animal() { console.log("Animal")}
function Bird() { console.log("Bird")}
function Dog() { console.log("Dog")}

Bird.prototype = Object.create(Animal.prototype);
Dog.prototype = Object.create(Animal.prototype);


duck = new Bird();
beagle = new Dog();


In the above code - we inherit Bird and Dog from Animal.
Their prototype will be animal. So by Default Bird.constructor will be pointing to Animal constructor.



When new Bird() is executed. I expect "Animal to be logged on console" but Bird is logged. Since the constructor is Animal. Animal constructor should be executed right? Correct my understanding







javascript object






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 25 '18 at 17:28









Tharun26Tharun26

150110




150110








  • 1





    your assertions are not correct.

    – Pointy
    Nov 25 '18 at 17:30











  • Can you tell me the reasons @Pointy

    – Tharun26
    Nov 25 '18 at 17:31













  • yes working on it :)

    – Pointy
    Nov 25 '18 at 17:32











  • prototype and constructor are different things.

    – trincot
    Nov 25 '18 at 17:34






  • 1





    "When new Bird() is executed I expect "Animal" to be logged on console" - Why? Bird is defined as function Bird() { console.log("Bird") } so that's what you get when calling it.

    – Bergi
    Nov 25 '18 at 17:39
















  • 1





    your assertions are not correct.

    – Pointy
    Nov 25 '18 at 17:30











  • Can you tell me the reasons @Pointy

    – Tharun26
    Nov 25 '18 at 17:31













  • yes working on it :)

    – Pointy
    Nov 25 '18 at 17:32











  • prototype and constructor are different things.

    – trincot
    Nov 25 '18 at 17:34






  • 1





    "When new Bird() is executed I expect "Animal" to be logged on console" - Why? Bird is defined as function Bird() { console.log("Bird") } so that's what you get when calling it.

    – Bergi
    Nov 25 '18 at 17:39










1




1





your assertions are not correct.

– Pointy
Nov 25 '18 at 17:30





your assertions are not correct.

– Pointy
Nov 25 '18 at 17:30













Can you tell me the reasons @Pointy

– Tharun26
Nov 25 '18 at 17:31







Can you tell me the reasons @Pointy

– Tharun26
Nov 25 '18 at 17:31















yes working on it :)

– Pointy
Nov 25 '18 at 17:32





yes working on it :)

– Pointy
Nov 25 '18 at 17:32













prototype and constructor are different things.

– trincot
Nov 25 '18 at 17:34





prototype and constructor are different things.

– trincot
Nov 25 '18 at 17:34




1




1





"When new Bird() is executed I expect "Animal" to be logged on console" - Why? Bird is defined as function Bird() { console.log("Bird") } so that's what you get when calling it.

– Bergi
Nov 25 '18 at 17:39







"When new Bird() is executed I expect "Animal" to be logged on console" - Why? Bird is defined as function Bird() { console.log("Bird") } so that's what you get when calling it.

– Bergi
Nov 25 '18 at 17:39














2 Answers
2






active

oldest

votes


















4














You are confusing inheritance with constructor calls. When you say:



duck = new Bird();


you are making an explicit call to the Bird constructor function so, of course, Bird will fire.





While Object.create() is a handy way of causing one object to inherit from another, you still have to manually set up the constructor chain. A good way to understand this is when both constructors take arguments (shown below).



See comments inline:






function Animal(gender) {
// The argument allows the instance property to initialize.
// gender will be a property of Animal and will be inherited
// by anything that inherits from Animal later. But, that
// doesn't change the fact that the Animal constructor
// must be called and passed the gender for the Animal
// to be properly initialized.
this.gender = gender;

// Get the caller of this function (non-standard technique - just used for demo).
// If the caller is null, it means that Animal was called directly. If not,
// we can get the name of the calling function:
var caller = Animal.caller ? Animal.caller.name : "Animal";

// Report of newly constructed Animal
console.log("Animal is a " + this.gender + ". (called by: " + caller + ")");
}


function Bird(gender, canFly) {
// Because a bird inherits from an Animal, you have
// to manually ensure that when a new Bird is created
// the Animal constructor gets called. You can see
// why this is necessary as we have a situation where
// the prototype's constructor is expecting an argument
// that we've received when the constructor of the
// derived object was called. We certainly don't want
// to have to rewrite the code that sets the gender, so
// we call the prototype's constructor and pass it what
// it is expecting and allow it to do some of the object
// initialization for us:
Animal.prototype.constructor.call(this, gender);

// Arguments meant for the current constructor are handled
// in the current constructor
this.canFly = canFly

// The inherited properties are available:
console.log("Bird is a " + this.gender + " and it can fly: " + this.canFly);
}

// This just causes Bird to inherit from Animal. This alone
// doesn't cause the Animal constructor to fire when new Bird()
// is executed.
Bird.prototype = Object.create(Animal.prototype);

// By using a different prototype, we have wiped out the native
// constructor so we will reset just the contstructor so that
// constructions of Bird work properly
Bird.prototype.constructor = Bird;

// Just a test to show that making an Animal properly
// requires that the Animal constructor be called and
// passed a gender.
console.log("--- Creating New Animal ---");
var generic = new Animal("male");

// You are explicitly invoking the Bird constructor here.
// It's going to fire that function. That function, in turn,
// is configured to invoke the prototype object's constructor.
// The gender property will be handled by the Animal constructor
// and the canFly will be handled by the Bird constructor.
console.log("--- Creating New Bird ---");
duck = new Bird("female", false);

// ************************************************

function Falcon(gender, canFly, trained){
// We'll pass the arguments needed by the parent object to it
Bird.prototype.constructor.call(this, gender, canFly);

// And set current instance properties right here
this.trained = trained;

console.log("Bird is a " + this.gender + ", can fly: " + this.canFly + " and is trained: " + this.trained);
}

Falcon.prototype = Object.create(Bird.prototype);

// By using a different prototype, we have wiped out the native
// constructor so we will reset just the contstructor so that
// constructions of Falcon work properly
Falcon.prototype.constructor = Falcon;

console.log("--- Creating New Falcon ---");
let f = new Falcon("female", true, false);








share|improve this answer


























  • When you set the Bird prototype to Bird.prototype = Object.create(Animal.prototype); what happens to Bird.prototype.constructor? If I want to make a class that inherits from Bird how do I call it's constructor?

    – Mark Meyer
    Nov 25 '18 at 18:07











  • @MarkMeyer When you set Bird.prototype = Object.create(Animal.prototype), it doesn't mean that when you invoke Bird() that Animal() will fire. It simply means that Bird.prototype now equals Animal.prototype. And, Bird.prototype.constructor now equals Animal. But, that's where you are getting confused. Bird.prototype.constructor == Animal (because Bird.prototype is Animal), not Bird.constructor. That is still Bird.

    – Scott Marcus
    Nov 25 '18 at 18:11













  • I think you misunderstood me. When you subclass animal you do: Animal.prototype.constructor.call(this, gender) to set the super's instance variables like gender. Now lets say I want to make a Falcon class that inherits from Bird so in it's constructor I call Bird.prototype.constructor.call(this, gender, true) Does it set canFly to true on my Falcon instance? Easy to show in code: repl.it/@ak_mark/GroundedLastEvents The issue is the Bird.prototype.constructor no longer points to Bird().

    – Mark Meyer
    Nov 25 '18 at 18:22













  • All I'm saying is that if I try to subclass Bird the same way Bird subclasses Animal it doesn't work. I'm doing exactly the same thing with Falcon in the repl.it; repl.it/@ak_mark/GroundedLastEvents What am I missing in the repl?

    – Mark Meyer
    Nov 25 '18 at 18:44













  • @MarkMeyer I see what you are saying. Yes, swapping the prototype does become an issue here and the solution is to manually correct the prototype.constructor after setting the prototype. This works because Object.create() make a new, distinct instance of the prototype object for the sub-object. Changing its constructor won't change it for the entire group - only for derived types. I've updated my answer to show this.

    – Scott Marcus
    Nov 25 '18 at 18:55



















2














The statement



Bird.prototype = Object.create(Animal.prototype);


makes the prototype object of the Bird constructor be a new object whose own prototype is the Animal prototype, not the Animal constructor itself.



Thus



duck = new Bird()


makes a new object whose constructor is Bird, whose prototype is the Bird prototype, which in turn inherits from the Animal prototype.



This way, your Animal prototype could have a method called eat(), so a call to



duck.eat("fish")


would effectively be a call to the eat() method on the Animal prototype. Why? Well there's no "eat" property directly on the duck object, and none on the Bird prototype, but there is an "eat" property on the Animal prototype.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53470033%2fwhy-constructor-of-a-object-is-executed-even-though-we-change-it-manually-to-ano%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    4














    You are confusing inheritance with constructor calls. When you say:



    duck = new Bird();


    you are making an explicit call to the Bird constructor function so, of course, Bird will fire.





    While Object.create() is a handy way of causing one object to inherit from another, you still have to manually set up the constructor chain. A good way to understand this is when both constructors take arguments (shown below).



    See comments inline:






    function Animal(gender) {
    // The argument allows the instance property to initialize.
    // gender will be a property of Animal and will be inherited
    // by anything that inherits from Animal later. But, that
    // doesn't change the fact that the Animal constructor
    // must be called and passed the gender for the Animal
    // to be properly initialized.
    this.gender = gender;

    // Get the caller of this function (non-standard technique - just used for demo).
    // If the caller is null, it means that Animal was called directly. If not,
    // we can get the name of the calling function:
    var caller = Animal.caller ? Animal.caller.name : "Animal";

    // Report of newly constructed Animal
    console.log("Animal is a " + this.gender + ". (called by: " + caller + ")");
    }


    function Bird(gender, canFly) {
    // Because a bird inherits from an Animal, you have
    // to manually ensure that when a new Bird is created
    // the Animal constructor gets called. You can see
    // why this is necessary as we have a situation where
    // the prototype's constructor is expecting an argument
    // that we've received when the constructor of the
    // derived object was called. We certainly don't want
    // to have to rewrite the code that sets the gender, so
    // we call the prototype's constructor and pass it what
    // it is expecting and allow it to do some of the object
    // initialization for us:
    Animal.prototype.constructor.call(this, gender);

    // Arguments meant for the current constructor are handled
    // in the current constructor
    this.canFly = canFly

    // The inherited properties are available:
    console.log("Bird is a " + this.gender + " and it can fly: " + this.canFly);
    }

    // This just causes Bird to inherit from Animal. This alone
    // doesn't cause the Animal constructor to fire when new Bird()
    // is executed.
    Bird.prototype = Object.create(Animal.prototype);

    // By using a different prototype, we have wiped out the native
    // constructor so we will reset just the contstructor so that
    // constructions of Bird work properly
    Bird.prototype.constructor = Bird;

    // Just a test to show that making an Animal properly
    // requires that the Animal constructor be called and
    // passed a gender.
    console.log("--- Creating New Animal ---");
    var generic = new Animal("male");

    // You are explicitly invoking the Bird constructor here.
    // It's going to fire that function. That function, in turn,
    // is configured to invoke the prototype object's constructor.
    // The gender property will be handled by the Animal constructor
    // and the canFly will be handled by the Bird constructor.
    console.log("--- Creating New Bird ---");
    duck = new Bird("female", false);

    // ************************************************

    function Falcon(gender, canFly, trained){
    // We'll pass the arguments needed by the parent object to it
    Bird.prototype.constructor.call(this, gender, canFly);

    // And set current instance properties right here
    this.trained = trained;

    console.log("Bird is a " + this.gender + ", can fly: " + this.canFly + " and is trained: " + this.trained);
    }

    Falcon.prototype = Object.create(Bird.prototype);

    // By using a different prototype, we have wiped out the native
    // constructor so we will reset just the contstructor so that
    // constructions of Falcon work properly
    Falcon.prototype.constructor = Falcon;

    console.log("--- Creating New Falcon ---");
    let f = new Falcon("female", true, false);








    share|improve this answer


























    • When you set the Bird prototype to Bird.prototype = Object.create(Animal.prototype); what happens to Bird.prototype.constructor? If I want to make a class that inherits from Bird how do I call it's constructor?

      – Mark Meyer
      Nov 25 '18 at 18:07











    • @MarkMeyer When you set Bird.prototype = Object.create(Animal.prototype), it doesn't mean that when you invoke Bird() that Animal() will fire. It simply means that Bird.prototype now equals Animal.prototype. And, Bird.prototype.constructor now equals Animal. But, that's where you are getting confused. Bird.prototype.constructor == Animal (because Bird.prototype is Animal), not Bird.constructor. That is still Bird.

      – Scott Marcus
      Nov 25 '18 at 18:11













    • I think you misunderstood me. When you subclass animal you do: Animal.prototype.constructor.call(this, gender) to set the super's instance variables like gender. Now lets say I want to make a Falcon class that inherits from Bird so in it's constructor I call Bird.prototype.constructor.call(this, gender, true) Does it set canFly to true on my Falcon instance? Easy to show in code: repl.it/@ak_mark/GroundedLastEvents The issue is the Bird.prototype.constructor no longer points to Bird().

      – Mark Meyer
      Nov 25 '18 at 18:22













    • All I'm saying is that if I try to subclass Bird the same way Bird subclasses Animal it doesn't work. I'm doing exactly the same thing with Falcon in the repl.it; repl.it/@ak_mark/GroundedLastEvents What am I missing in the repl?

      – Mark Meyer
      Nov 25 '18 at 18:44













    • @MarkMeyer I see what you are saying. Yes, swapping the prototype does become an issue here and the solution is to manually correct the prototype.constructor after setting the prototype. This works because Object.create() make a new, distinct instance of the prototype object for the sub-object. Changing its constructor won't change it for the entire group - only for derived types. I've updated my answer to show this.

      – Scott Marcus
      Nov 25 '18 at 18:55
















    4














    You are confusing inheritance with constructor calls. When you say:



    duck = new Bird();


    you are making an explicit call to the Bird constructor function so, of course, Bird will fire.





    While Object.create() is a handy way of causing one object to inherit from another, you still have to manually set up the constructor chain. A good way to understand this is when both constructors take arguments (shown below).



    See comments inline:






    function Animal(gender) {
    // The argument allows the instance property to initialize.
    // gender will be a property of Animal and will be inherited
    // by anything that inherits from Animal later. But, that
    // doesn't change the fact that the Animal constructor
    // must be called and passed the gender for the Animal
    // to be properly initialized.
    this.gender = gender;

    // Get the caller of this function (non-standard technique - just used for demo).
    // If the caller is null, it means that Animal was called directly. If not,
    // we can get the name of the calling function:
    var caller = Animal.caller ? Animal.caller.name : "Animal";

    // Report of newly constructed Animal
    console.log("Animal is a " + this.gender + ". (called by: " + caller + ")");
    }


    function Bird(gender, canFly) {
    // Because a bird inherits from an Animal, you have
    // to manually ensure that when a new Bird is created
    // the Animal constructor gets called. You can see
    // why this is necessary as we have a situation where
    // the prototype's constructor is expecting an argument
    // that we've received when the constructor of the
    // derived object was called. We certainly don't want
    // to have to rewrite the code that sets the gender, so
    // we call the prototype's constructor and pass it what
    // it is expecting and allow it to do some of the object
    // initialization for us:
    Animal.prototype.constructor.call(this, gender);

    // Arguments meant for the current constructor are handled
    // in the current constructor
    this.canFly = canFly

    // The inherited properties are available:
    console.log("Bird is a " + this.gender + " and it can fly: " + this.canFly);
    }

    // This just causes Bird to inherit from Animal. This alone
    // doesn't cause the Animal constructor to fire when new Bird()
    // is executed.
    Bird.prototype = Object.create(Animal.prototype);

    // By using a different prototype, we have wiped out the native
    // constructor so we will reset just the contstructor so that
    // constructions of Bird work properly
    Bird.prototype.constructor = Bird;

    // Just a test to show that making an Animal properly
    // requires that the Animal constructor be called and
    // passed a gender.
    console.log("--- Creating New Animal ---");
    var generic = new Animal("male");

    // You are explicitly invoking the Bird constructor here.
    // It's going to fire that function. That function, in turn,
    // is configured to invoke the prototype object's constructor.
    // The gender property will be handled by the Animal constructor
    // and the canFly will be handled by the Bird constructor.
    console.log("--- Creating New Bird ---");
    duck = new Bird("female", false);

    // ************************************************

    function Falcon(gender, canFly, trained){
    // We'll pass the arguments needed by the parent object to it
    Bird.prototype.constructor.call(this, gender, canFly);

    // And set current instance properties right here
    this.trained = trained;

    console.log("Bird is a " + this.gender + ", can fly: " + this.canFly + " and is trained: " + this.trained);
    }

    Falcon.prototype = Object.create(Bird.prototype);

    // By using a different prototype, we have wiped out the native
    // constructor so we will reset just the contstructor so that
    // constructions of Falcon work properly
    Falcon.prototype.constructor = Falcon;

    console.log("--- Creating New Falcon ---");
    let f = new Falcon("female", true, false);








    share|improve this answer


























    • When you set the Bird prototype to Bird.prototype = Object.create(Animal.prototype); what happens to Bird.prototype.constructor? If I want to make a class that inherits from Bird how do I call it's constructor?

      – Mark Meyer
      Nov 25 '18 at 18:07











    • @MarkMeyer When you set Bird.prototype = Object.create(Animal.prototype), it doesn't mean that when you invoke Bird() that Animal() will fire. It simply means that Bird.prototype now equals Animal.prototype. And, Bird.prototype.constructor now equals Animal. But, that's where you are getting confused. Bird.prototype.constructor == Animal (because Bird.prototype is Animal), not Bird.constructor. That is still Bird.

      – Scott Marcus
      Nov 25 '18 at 18:11













    • I think you misunderstood me. When you subclass animal you do: Animal.prototype.constructor.call(this, gender) to set the super's instance variables like gender. Now lets say I want to make a Falcon class that inherits from Bird so in it's constructor I call Bird.prototype.constructor.call(this, gender, true) Does it set canFly to true on my Falcon instance? Easy to show in code: repl.it/@ak_mark/GroundedLastEvents The issue is the Bird.prototype.constructor no longer points to Bird().

      – Mark Meyer
      Nov 25 '18 at 18:22













    • All I'm saying is that if I try to subclass Bird the same way Bird subclasses Animal it doesn't work. I'm doing exactly the same thing with Falcon in the repl.it; repl.it/@ak_mark/GroundedLastEvents What am I missing in the repl?

      – Mark Meyer
      Nov 25 '18 at 18:44













    • @MarkMeyer I see what you are saying. Yes, swapping the prototype does become an issue here and the solution is to manually correct the prototype.constructor after setting the prototype. This works because Object.create() make a new, distinct instance of the prototype object for the sub-object. Changing its constructor won't change it for the entire group - only for derived types. I've updated my answer to show this.

      – Scott Marcus
      Nov 25 '18 at 18:55














    4












    4








    4







    You are confusing inheritance with constructor calls. When you say:



    duck = new Bird();


    you are making an explicit call to the Bird constructor function so, of course, Bird will fire.





    While Object.create() is a handy way of causing one object to inherit from another, you still have to manually set up the constructor chain. A good way to understand this is when both constructors take arguments (shown below).



    See comments inline:






    function Animal(gender) {
    // The argument allows the instance property to initialize.
    // gender will be a property of Animal and will be inherited
    // by anything that inherits from Animal later. But, that
    // doesn't change the fact that the Animal constructor
    // must be called and passed the gender for the Animal
    // to be properly initialized.
    this.gender = gender;

    // Get the caller of this function (non-standard technique - just used for demo).
    // If the caller is null, it means that Animal was called directly. If not,
    // we can get the name of the calling function:
    var caller = Animal.caller ? Animal.caller.name : "Animal";

    // Report of newly constructed Animal
    console.log("Animal is a " + this.gender + ". (called by: " + caller + ")");
    }


    function Bird(gender, canFly) {
    // Because a bird inherits from an Animal, you have
    // to manually ensure that when a new Bird is created
    // the Animal constructor gets called. You can see
    // why this is necessary as we have a situation where
    // the prototype's constructor is expecting an argument
    // that we've received when the constructor of the
    // derived object was called. We certainly don't want
    // to have to rewrite the code that sets the gender, so
    // we call the prototype's constructor and pass it what
    // it is expecting and allow it to do some of the object
    // initialization for us:
    Animal.prototype.constructor.call(this, gender);

    // Arguments meant for the current constructor are handled
    // in the current constructor
    this.canFly = canFly

    // The inherited properties are available:
    console.log("Bird is a " + this.gender + " and it can fly: " + this.canFly);
    }

    // This just causes Bird to inherit from Animal. This alone
    // doesn't cause the Animal constructor to fire when new Bird()
    // is executed.
    Bird.prototype = Object.create(Animal.prototype);

    // By using a different prototype, we have wiped out the native
    // constructor so we will reset just the contstructor so that
    // constructions of Bird work properly
    Bird.prototype.constructor = Bird;

    // Just a test to show that making an Animal properly
    // requires that the Animal constructor be called and
    // passed a gender.
    console.log("--- Creating New Animal ---");
    var generic = new Animal("male");

    // You are explicitly invoking the Bird constructor here.
    // It's going to fire that function. That function, in turn,
    // is configured to invoke the prototype object's constructor.
    // The gender property will be handled by the Animal constructor
    // and the canFly will be handled by the Bird constructor.
    console.log("--- Creating New Bird ---");
    duck = new Bird("female", false);

    // ************************************************

    function Falcon(gender, canFly, trained){
    // We'll pass the arguments needed by the parent object to it
    Bird.prototype.constructor.call(this, gender, canFly);

    // And set current instance properties right here
    this.trained = trained;

    console.log("Bird is a " + this.gender + ", can fly: " + this.canFly + " and is trained: " + this.trained);
    }

    Falcon.prototype = Object.create(Bird.prototype);

    // By using a different prototype, we have wiped out the native
    // constructor so we will reset just the contstructor so that
    // constructions of Falcon work properly
    Falcon.prototype.constructor = Falcon;

    console.log("--- Creating New Falcon ---");
    let f = new Falcon("female", true, false);








    share|improve this answer















    You are confusing inheritance with constructor calls. When you say:



    duck = new Bird();


    you are making an explicit call to the Bird constructor function so, of course, Bird will fire.





    While Object.create() is a handy way of causing one object to inherit from another, you still have to manually set up the constructor chain. A good way to understand this is when both constructors take arguments (shown below).



    See comments inline:






    function Animal(gender) {
    // The argument allows the instance property to initialize.
    // gender will be a property of Animal and will be inherited
    // by anything that inherits from Animal later. But, that
    // doesn't change the fact that the Animal constructor
    // must be called and passed the gender for the Animal
    // to be properly initialized.
    this.gender = gender;

    // Get the caller of this function (non-standard technique - just used for demo).
    // If the caller is null, it means that Animal was called directly. If not,
    // we can get the name of the calling function:
    var caller = Animal.caller ? Animal.caller.name : "Animal";

    // Report of newly constructed Animal
    console.log("Animal is a " + this.gender + ". (called by: " + caller + ")");
    }


    function Bird(gender, canFly) {
    // Because a bird inherits from an Animal, you have
    // to manually ensure that when a new Bird is created
    // the Animal constructor gets called. You can see
    // why this is necessary as we have a situation where
    // the prototype's constructor is expecting an argument
    // that we've received when the constructor of the
    // derived object was called. We certainly don't want
    // to have to rewrite the code that sets the gender, so
    // we call the prototype's constructor and pass it what
    // it is expecting and allow it to do some of the object
    // initialization for us:
    Animal.prototype.constructor.call(this, gender);

    // Arguments meant for the current constructor are handled
    // in the current constructor
    this.canFly = canFly

    // The inherited properties are available:
    console.log("Bird is a " + this.gender + " and it can fly: " + this.canFly);
    }

    // This just causes Bird to inherit from Animal. This alone
    // doesn't cause the Animal constructor to fire when new Bird()
    // is executed.
    Bird.prototype = Object.create(Animal.prototype);

    // By using a different prototype, we have wiped out the native
    // constructor so we will reset just the contstructor so that
    // constructions of Bird work properly
    Bird.prototype.constructor = Bird;

    // Just a test to show that making an Animal properly
    // requires that the Animal constructor be called and
    // passed a gender.
    console.log("--- Creating New Animal ---");
    var generic = new Animal("male");

    // You are explicitly invoking the Bird constructor here.
    // It's going to fire that function. That function, in turn,
    // is configured to invoke the prototype object's constructor.
    // The gender property will be handled by the Animal constructor
    // and the canFly will be handled by the Bird constructor.
    console.log("--- Creating New Bird ---");
    duck = new Bird("female", false);

    // ************************************************

    function Falcon(gender, canFly, trained){
    // We'll pass the arguments needed by the parent object to it
    Bird.prototype.constructor.call(this, gender, canFly);

    // And set current instance properties right here
    this.trained = trained;

    console.log("Bird is a " + this.gender + ", can fly: " + this.canFly + " and is trained: " + this.trained);
    }

    Falcon.prototype = Object.create(Bird.prototype);

    // By using a different prototype, we have wiped out the native
    // constructor so we will reset just the contstructor so that
    // constructions of Falcon work properly
    Falcon.prototype.constructor = Falcon;

    console.log("--- Creating New Falcon ---");
    let f = new Falcon("female", true, false);








    function Animal(gender) {
    // The argument allows the instance property to initialize.
    // gender will be a property of Animal and will be inherited
    // by anything that inherits from Animal later. But, that
    // doesn't change the fact that the Animal constructor
    // must be called and passed the gender for the Animal
    // to be properly initialized.
    this.gender = gender;

    // Get the caller of this function (non-standard technique - just used for demo).
    // If the caller is null, it means that Animal was called directly. If not,
    // we can get the name of the calling function:
    var caller = Animal.caller ? Animal.caller.name : "Animal";

    // Report of newly constructed Animal
    console.log("Animal is a " + this.gender + ". (called by: " + caller + ")");
    }


    function Bird(gender, canFly) {
    // Because a bird inherits from an Animal, you have
    // to manually ensure that when a new Bird is created
    // the Animal constructor gets called. You can see
    // why this is necessary as we have a situation where
    // the prototype's constructor is expecting an argument
    // that we've received when the constructor of the
    // derived object was called. We certainly don't want
    // to have to rewrite the code that sets the gender, so
    // we call the prototype's constructor and pass it what
    // it is expecting and allow it to do some of the object
    // initialization for us:
    Animal.prototype.constructor.call(this, gender);

    // Arguments meant for the current constructor are handled
    // in the current constructor
    this.canFly = canFly

    // The inherited properties are available:
    console.log("Bird is a " + this.gender + " and it can fly: " + this.canFly);
    }

    // This just causes Bird to inherit from Animal. This alone
    // doesn't cause the Animal constructor to fire when new Bird()
    // is executed.
    Bird.prototype = Object.create(Animal.prototype);

    // By using a different prototype, we have wiped out the native
    // constructor so we will reset just the contstructor so that
    // constructions of Bird work properly
    Bird.prototype.constructor = Bird;

    // Just a test to show that making an Animal properly
    // requires that the Animal constructor be called and
    // passed a gender.
    console.log("--- Creating New Animal ---");
    var generic = new Animal("male");

    // You are explicitly invoking the Bird constructor here.
    // It's going to fire that function. That function, in turn,
    // is configured to invoke the prototype object's constructor.
    // The gender property will be handled by the Animal constructor
    // and the canFly will be handled by the Bird constructor.
    console.log("--- Creating New Bird ---");
    duck = new Bird("female", false);

    // ************************************************

    function Falcon(gender, canFly, trained){
    // We'll pass the arguments needed by the parent object to it
    Bird.prototype.constructor.call(this, gender, canFly);

    // And set current instance properties right here
    this.trained = trained;

    console.log("Bird is a " + this.gender + ", can fly: " + this.canFly + " and is trained: " + this.trained);
    }

    Falcon.prototype = Object.create(Bird.prototype);

    // By using a different prototype, we have wiped out the native
    // constructor so we will reset just the contstructor so that
    // constructions of Falcon work properly
    Falcon.prototype.constructor = Falcon;

    console.log("--- Creating New Falcon ---");
    let f = new Falcon("female", true, false);





    function Animal(gender) {
    // The argument allows the instance property to initialize.
    // gender will be a property of Animal and will be inherited
    // by anything that inherits from Animal later. But, that
    // doesn't change the fact that the Animal constructor
    // must be called and passed the gender for the Animal
    // to be properly initialized.
    this.gender = gender;

    // Get the caller of this function (non-standard technique - just used for demo).
    // If the caller is null, it means that Animal was called directly. If not,
    // we can get the name of the calling function:
    var caller = Animal.caller ? Animal.caller.name : "Animal";

    // Report of newly constructed Animal
    console.log("Animal is a " + this.gender + ". (called by: " + caller + ")");
    }


    function Bird(gender, canFly) {
    // Because a bird inherits from an Animal, you have
    // to manually ensure that when a new Bird is created
    // the Animal constructor gets called. You can see
    // why this is necessary as we have a situation where
    // the prototype's constructor is expecting an argument
    // that we've received when the constructor of the
    // derived object was called. We certainly don't want
    // to have to rewrite the code that sets the gender, so
    // we call the prototype's constructor and pass it what
    // it is expecting and allow it to do some of the object
    // initialization for us:
    Animal.prototype.constructor.call(this, gender);

    // Arguments meant for the current constructor are handled
    // in the current constructor
    this.canFly = canFly

    // The inherited properties are available:
    console.log("Bird is a " + this.gender + " and it can fly: " + this.canFly);
    }

    // This just causes Bird to inherit from Animal. This alone
    // doesn't cause the Animal constructor to fire when new Bird()
    // is executed.
    Bird.prototype = Object.create(Animal.prototype);

    // By using a different prototype, we have wiped out the native
    // constructor so we will reset just the contstructor so that
    // constructions of Bird work properly
    Bird.prototype.constructor = Bird;

    // Just a test to show that making an Animal properly
    // requires that the Animal constructor be called and
    // passed a gender.
    console.log("--- Creating New Animal ---");
    var generic = new Animal("male");

    // You are explicitly invoking the Bird constructor here.
    // It's going to fire that function. That function, in turn,
    // is configured to invoke the prototype object's constructor.
    // The gender property will be handled by the Animal constructor
    // and the canFly will be handled by the Bird constructor.
    console.log("--- Creating New Bird ---");
    duck = new Bird("female", false);

    // ************************************************

    function Falcon(gender, canFly, trained){
    // We'll pass the arguments needed by the parent object to it
    Bird.prototype.constructor.call(this, gender, canFly);

    // And set current instance properties right here
    this.trained = trained;

    console.log("Bird is a " + this.gender + ", can fly: " + this.canFly + " and is trained: " + this.trained);
    }

    Falcon.prototype = Object.create(Bird.prototype);

    // By using a different prototype, we have wiped out the native
    // constructor so we will reset just the contstructor so that
    // constructions of Falcon work properly
    Falcon.prototype.constructor = Falcon;

    console.log("--- Creating New Falcon ---");
    let f = new Falcon("female", true, false);






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 25 '18 at 18:53

























    answered Nov 25 '18 at 17:34









    Scott MarcusScott Marcus

    39.7k52040




    39.7k52040













    • When you set the Bird prototype to Bird.prototype = Object.create(Animal.prototype); what happens to Bird.prototype.constructor? If I want to make a class that inherits from Bird how do I call it's constructor?

      – Mark Meyer
      Nov 25 '18 at 18:07











    • @MarkMeyer When you set Bird.prototype = Object.create(Animal.prototype), it doesn't mean that when you invoke Bird() that Animal() will fire. It simply means that Bird.prototype now equals Animal.prototype. And, Bird.prototype.constructor now equals Animal. But, that's where you are getting confused. Bird.prototype.constructor == Animal (because Bird.prototype is Animal), not Bird.constructor. That is still Bird.

      – Scott Marcus
      Nov 25 '18 at 18:11













    • I think you misunderstood me. When you subclass animal you do: Animal.prototype.constructor.call(this, gender) to set the super's instance variables like gender. Now lets say I want to make a Falcon class that inherits from Bird so in it's constructor I call Bird.prototype.constructor.call(this, gender, true) Does it set canFly to true on my Falcon instance? Easy to show in code: repl.it/@ak_mark/GroundedLastEvents The issue is the Bird.prototype.constructor no longer points to Bird().

      – Mark Meyer
      Nov 25 '18 at 18:22













    • All I'm saying is that if I try to subclass Bird the same way Bird subclasses Animal it doesn't work. I'm doing exactly the same thing with Falcon in the repl.it; repl.it/@ak_mark/GroundedLastEvents What am I missing in the repl?

      – Mark Meyer
      Nov 25 '18 at 18:44













    • @MarkMeyer I see what you are saying. Yes, swapping the prototype does become an issue here and the solution is to manually correct the prototype.constructor after setting the prototype. This works because Object.create() make a new, distinct instance of the prototype object for the sub-object. Changing its constructor won't change it for the entire group - only for derived types. I've updated my answer to show this.

      – Scott Marcus
      Nov 25 '18 at 18:55



















    • When you set the Bird prototype to Bird.prototype = Object.create(Animal.prototype); what happens to Bird.prototype.constructor? If I want to make a class that inherits from Bird how do I call it's constructor?

      – Mark Meyer
      Nov 25 '18 at 18:07











    • @MarkMeyer When you set Bird.prototype = Object.create(Animal.prototype), it doesn't mean that when you invoke Bird() that Animal() will fire. It simply means that Bird.prototype now equals Animal.prototype. And, Bird.prototype.constructor now equals Animal. But, that's where you are getting confused. Bird.prototype.constructor == Animal (because Bird.prototype is Animal), not Bird.constructor. That is still Bird.

      – Scott Marcus
      Nov 25 '18 at 18:11













    • I think you misunderstood me. When you subclass animal you do: Animal.prototype.constructor.call(this, gender) to set the super's instance variables like gender. Now lets say I want to make a Falcon class that inherits from Bird so in it's constructor I call Bird.prototype.constructor.call(this, gender, true) Does it set canFly to true on my Falcon instance? Easy to show in code: repl.it/@ak_mark/GroundedLastEvents The issue is the Bird.prototype.constructor no longer points to Bird().

      – Mark Meyer
      Nov 25 '18 at 18:22













    • All I'm saying is that if I try to subclass Bird the same way Bird subclasses Animal it doesn't work. I'm doing exactly the same thing with Falcon in the repl.it; repl.it/@ak_mark/GroundedLastEvents What am I missing in the repl?

      – Mark Meyer
      Nov 25 '18 at 18:44













    • @MarkMeyer I see what you are saying. Yes, swapping the prototype does become an issue here and the solution is to manually correct the prototype.constructor after setting the prototype. This works because Object.create() make a new, distinct instance of the prototype object for the sub-object. Changing its constructor won't change it for the entire group - only for derived types. I've updated my answer to show this.

      – Scott Marcus
      Nov 25 '18 at 18:55

















    When you set the Bird prototype to Bird.prototype = Object.create(Animal.prototype); what happens to Bird.prototype.constructor? If I want to make a class that inherits from Bird how do I call it's constructor?

    – Mark Meyer
    Nov 25 '18 at 18:07





    When you set the Bird prototype to Bird.prototype = Object.create(Animal.prototype); what happens to Bird.prototype.constructor? If I want to make a class that inherits from Bird how do I call it's constructor?

    – Mark Meyer
    Nov 25 '18 at 18:07













    @MarkMeyer When you set Bird.prototype = Object.create(Animal.prototype), it doesn't mean that when you invoke Bird() that Animal() will fire. It simply means that Bird.prototype now equals Animal.prototype. And, Bird.prototype.constructor now equals Animal. But, that's where you are getting confused. Bird.prototype.constructor == Animal (because Bird.prototype is Animal), not Bird.constructor. That is still Bird.

    – Scott Marcus
    Nov 25 '18 at 18:11







    @MarkMeyer When you set Bird.prototype = Object.create(Animal.prototype), it doesn't mean that when you invoke Bird() that Animal() will fire. It simply means that Bird.prototype now equals Animal.prototype. And, Bird.prototype.constructor now equals Animal. But, that's where you are getting confused. Bird.prototype.constructor == Animal (because Bird.prototype is Animal), not Bird.constructor. That is still Bird.

    – Scott Marcus
    Nov 25 '18 at 18:11















    I think you misunderstood me. When you subclass animal you do: Animal.prototype.constructor.call(this, gender) to set the super's instance variables like gender. Now lets say I want to make a Falcon class that inherits from Bird so in it's constructor I call Bird.prototype.constructor.call(this, gender, true) Does it set canFly to true on my Falcon instance? Easy to show in code: repl.it/@ak_mark/GroundedLastEvents The issue is the Bird.prototype.constructor no longer points to Bird().

    – Mark Meyer
    Nov 25 '18 at 18:22







    I think you misunderstood me. When you subclass animal you do: Animal.prototype.constructor.call(this, gender) to set the super's instance variables like gender. Now lets say I want to make a Falcon class that inherits from Bird so in it's constructor I call Bird.prototype.constructor.call(this, gender, true) Does it set canFly to true on my Falcon instance? Easy to show in code: repl.it/@ak_mark/GroundedLastEvents The issue is the Bird.prototype.constructor no longer points to Bird().

    – Mark Meyer
    Nov 25 '18 at 18:22















    All I'm saying is that if I try to subclass Bird the same way Bird subclasses Animal it doesn't work. I'm doing exactly the same thing with Falcon in the repl.it; repl.it/@ak_mark/GroundedLastEvents What am I missing in the repl?

    – Mark Meyer
    Nov 25 '18 at 18:44







    All I'm saying is that if I try to subclass Bird the same way Bird subclasses Animal it doesn't work. I'm doing exactly the same thing with Falcon in the repl.it; repl.it/@ak_mark/GroundedLastEvents What am I missing in the repl?

    – Mark Meyer
    Nov 25 '18 at 18:44















    @MarkMeyer I see what you are saying. Yes, swapping the prototype does become an issue here and the solution is to manually correct the prototype.constructor after setting the prototype. This works because Object.create() make a new, distinct instance of the prototype object for the sub-object. Changing its constructor won't change it for the entire group - only for derived types. I've updated my answer to show this.

    – Scott Marcus
    Nov 25 '18 at 18:55





    @MarkMeyer I see what you are saying. Yes, swapping the prototype does become an issue here and the solution is to manually correct the prototype.constructor after setting the prototype. This works because Object.create() make a new, distinct instance of the prototype object for the sub-object. Changing its constructor won't change it for the entire group - only for derived types. I've updated my answer to show this.

    – Scott Marcus
    Nov 25 '18 at 18:55













    2














    The statement



    Bird.prototype = Object.create(Animal.prototype);


    makes the prototype object of the Bird constructor be a new object whose own prototype is the Animal prototype, not the Animal constructor itself.



    Thus



    duck = new Bird()


    makes a new object whose constructor is Bird, whose prototype is the Bird prototype, which in turn inherits from the Animal prototype.



    This way, your Animal prototype could have a method called eat(), so a call to



    duck.eat("fish")


    would effectively be a call to the eat() method on the Animal prototype. Why? Well there's no "eat" property directly on the duck object, and none on the Bird prototype, but there is an "eat" property on the Animal prototype.






    share|improve this answer




























      2














      The statement



      Bird.prototype = Object.create(Animal.prototype);


      makes the prototype object of the Bird constructor be a new object whose own prototype is the Animal prototype, not the Animal constructor itself.



      Thus



      duck = new Bird()


      makes a new object whose constructor is Bird, whose prototype is the Bird prototype, which in turn inherits from the Animal prototype.



      This way, your Animal prototype could have a method called eat(), so a call to



      duck.eat("fish")


      would effectively be a call to the eat() method on the Animal prototype. Why? Well there's no "eat" property directly on the duck object, and none on the Bird prototype, but there is an "eat" property on the Animal prototype.






      share|improve this answer


























        2












        2








        2







        The statement



        Bird.prototype = Object.create(Animal.prototype);


        makes the prototype object of the Bird constructor be a new object whose own prototype is the Animal prototype, not the Animal constructor itself.



        Thus



        duck = new Bird()


        makes a new object whose constructor is Bird, whose prototype is the Bird prototype, which in turn inherits from the Animal prototype.



        This way, your Animal prototype could have a method called eat(), so a call to



        duck.eat("fish")


        would effectively be a call to the eat() method on the Animal prototype. Why? Well there's no "eat" property directly on the duck object, and none on the Bird prototype, but there is an "eat" property on the Animal prototype.






        share|improve this answer













        The statement



        Bird.prototype = Object.create(Animal.prototype);


        makes the prototype object of the Bird constructor be a new object whose own prototype is the Animal prototype, not the Animal constructor itself.



        Thus



        duck = new Bird()


        makes a new object whose constructor is Bird, whose prototype is the Bird prototype, which in turn inherits from the Animal prototype.



        This way, your Animal prototype could have a method called eat(), so a call to



        duck.eat("fish")


        would effectively be a call to the eat() method on the Animal prototype. Why? Well there's no "eat" property directly on the duck object, and none on the Bird prototype, but there is an "eat" property on the Animal prototype.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 25 '18 at 17:35









        PointyPointy

        319k44461527




        319k44461527






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53470033%2fwhy-constructor-of-a-object-is-executed-even-though-we-change-it-manually-to-ano%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Wiesbaden

            Marschland

            Dieringhausen