Javascript 有人能解释为什么原型链不应该';不要说“狗”——>`动物`->`生物`?

Javascript 有人能解释为什么原型链不应该';不要说“狗”——>`动物`->`生物`?,javascript,console,prototype,prototype-chain,Javascript,Console,Prototype,Prototype Chain,我一直在寻找Javascript原型继承的好例子,这个问题有一个很好的答案,所以我试图通过向原型链添加另一个对象类型来增加我的运气,我发现了一些奇怪的东西 原始列表中有Dog继承自Animal,我们可以在原型链中看到Animal。但是,如果我们添加生物并从中继承动物,那么动物将从报告的原型链中消失,如果我们使用console.info 有人能解释为什么原型链不应该说Dog->Animal->生物 下面是代码清单 "use strict"; //https://www.ty

我一直在寻找Javascript原型继承的好例子,这个问题有一个很好的答案,所以我试图通过向原型链添加另一个对象类型来增加我的运气,我发现了一些奇怪的东西

原始列表中有
Dog
继承自
Animal
,我们可以在原型链中看到
Animal
。但是,如果我们添加
生物
并从中继承
动物
,那么
动物
将从报告的原型链中消失,如果我们使用console.info

有人能解释为什么原型链不应该说
Dog
->
Animal
->
生物

下面是代码清单

"use strict";

//https://www.typescriptlang.org/docs/handbook/classes.html
var Creature = (function () {
    function Creature() {
        return this;
    }

    Creature.prototype.deadOrAlive = function () {
        console.log("alive"); //hard code for now
    }

    return Creature;
}());

var Animal = (function () {

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

    function Animal() {
        return this;
    }

    Animal.prototype.move = function (distanceInMeters) {
        if (distanceInMeters === void 0) {
            distanceInMeters = 0;
        }
        console.log("Animal moved " + distanceInMeters + "m.");
    };

    return Animal;
}());

var Dog = (function () {

    /* https://stackoverflow.com/questions/17392857/benefits-of-using-object-create-for-inheritance/17393153#answer-17393153 */
    Dog.prototype = Object.create(Animal.prototype);

    function Dog() {
        return this;
    }
    Dog.prototype.bark = function () {
        console.log("Woof! Woof!");
    };
    return Dog;
}());

var dog = new Dog();
dog.bark();
dog.move(10);
dog.bark();
dog.deadOrAlive();
//debugger; 

每个原型对象都有一个构造函数属性,该属性指向构造函数函数。(问题中的图像显示,
生物.prototype
有一个
构造函数
属性,该属性指向
生物
构造函数。)

您还需要在
Animal.prototype
对象上添加
constructor
属性,该属性指向
Animal
构造函数

// Animal 
Animal.prototype.constructor = Animal; 

// Dog (not required but better to add it on Dog.prototype as well)
Dog.prototype.constructor = Dog;
如果未在
Animal.prototype
对象上设置
constructor
属性,将在prototype链中查找
constructor
属性

动物。prototype
对象的原型是
生物。prototype
,由于它有一个
构造函数
属性,指向
生物
,您会看到
生物
而不是
动物
作为
狗的值

Animal.prototype
对象上设置
constructor
属性后,开发工具中的控制台将显示预期结果:

下面的代码片段显示了设置
Animal.prototype.constructor
属性之前和之后
dog.\uuuu proto\uuuu.constructor
的值

函数bioture(){}
函数Animal(){}
Animal.prototype=Object.create(biot.prototype);
函数Dog(){}
Dog.prototype=Object.create(Animal.prototype);
var dog=新的dog();
log(“在设置'Animal.prototype.constructor'之前”);
log(Object.getPrototypeOf(dog.constructor);
Animal.prototype.constructor=动物;
console.log(“在设置“Animal.prototype.constructor”之后”);

log(Object.getPrototypeOf(dog.constructor)
我参加的Javascript新兵训练营的一位同事提出了一个单行解决方案,只需使用
Object.setPrototypeOf(Animal.prototype,bioter.prototype)
。谢谢,雷

//https://www.typescriptlang.org/docs/handbook/classes.html
"use strict";

var Creature = (function () {
    function Creature() {
        return this;
    }

    Creature.prototype.deadOrAlive = function () {
        console.log("alive"); //hard code for now
    }

    return Creature;
}());

var Animal = (function () {
    Object.setPrototypeOf( Animal.prototype, Creature.prototype )

    function Animal() {
        return this;
    }

    Animal.prototype.move = function (distanceInMeters) {
        if (distanceInMeters === void 0) {
            distanceInMeters = 0;
        }
        console.log("Animal moved " + distanceInMeters + "m.");
    };

    return Animal;
}());

var Dog = (function () {
    /* https://stackoverflow.com/questions/17392857/benefits-of-using-object-create-for-inheritance/17393153#answer-17393153 */
    Object.setPrototypeOf( Dog.prototype, Animal.prototype )

    function Dog() {
        return this;
    }
    Dog.prototype.bark = function () {
        console.log("Woof! Woof!");
    };
    return Dog;
}());

var dog = new Dog();
dog.bark();
dog.move(10);
dog.bark();
dog.deadOrAlive();
//debugger;

如果您使用的是ES6
对象。setPrototypeOf
,您也可以只使用ES6
声明:-)对于ES5代码,仍然建议使用
对象。创建
,这很有教育意义。“有人能解释一下为什么原型链不应该说
->
动物
生物
?”-原型链是
dog
->
dog.prototype
->
Animal.prototype
->
生物。prototype
->
对象。prototype
->
空值
。调试器显示的只是这些对象上的派生标签,并不总是有用的。