Javascript 有人能解释为什么原型链不应该';不要说“狗”——>`动物`->`生物`?
我一直在寻找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
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
->空值
。调试器显示的只是这些对象上的派生标签,并不总是有用的。