JavaScript中如何继承具体的原型方法?
How to inherit specific prototype method in JavaScript?
我试图找到答案,但很难找到一个好的答案。
可能这个问题是众所周知的,但请帮助我。
我无法完成这项工作:
function Animal() {}
function Cat() {}
Animal.prototype.walk = function() { return 'I can walk' }
Animal.prototype.swim = function() { return 'I can swim' }
如果我写:
Cat.prototype = new Animal();
Cat继承了walk和swim方法,那么要让Cat只继承walk方法应该怎么写呢?
您可以分配一个原型对象 (*.prototype) 另一个 Object Literal ({}) 但要小心继承不再正常工作:
function Person() {}
Person.prototype.walk = function() { return 'I can walk' }
Person.prototype.swim = function() { return 'I can swim' }
function Man() {}
// select methods Man gets inherited here
// just assign certain methods from Person.prototype onto Man.prototype
// therefore Man.prototype inherites only walk method
Man.prototype = {
walk: Person.prototype.walk,
// so swim is not passed onto Man.prototype
// swim: Person.prototype.swim
};
var m = new Man();
// this throws an error
// because a object of type Man does not have got a swim method inherited
// m.swim(); Error!
console.log('is false: ', m instanceof Person);
console.log('parent constructor is Object: ', m.__proto__.__proto__.constructor);
但是正如您所看到的,一些检查以确保此对象是什么实例以及它从哪个超级父构造函数继承某些方法无法正常工作,但它们应该可以工作。
所以你最好以正确的方式使用继承:
function Person() {}
Person.prototype.walk = function() { return 'I can walk' }
Person.prototype.swim = function() { return 'I can swim' }
function Man() {}
Man.prototype = Object.create(Person.prototype);
var m = new Man();
// in this way Person gets every method that is assigned onto Person.prototype
// so swim method is available and can be used by objects of type Man now:
m.swim();
console.log('is true: ', m instanceof Person);
console.log('parent constructor is Person: ', m.__proto__.__proto__.constructor);
这样 instanceof 运算符和对超级父构造函数的引用就可以正常工作。通过这种方式,所有方法都立即分配给 Person,但通过引入额外的抽象或父构造函数,这可能是可以避免的。
希望对您有所帮助。
我认为主要问题不是如何让那只猫继承走路而不是摆动:我认为你展示的方式是不可能的,但这里的问题是对继承层次结构的不完全理解。
看,基本上你在说什么:猫是动物,所以他没有继承动物的所有行为是没有意义的。因为如果你说:Animal 被定义为可以 WALK 和 SWING 的人,然后你说:A Cat 是一种 Animal,那么 Cat MUST MUST WALK AND SWING。
我认为您的情况需要重新组织层次结构。也许你可以制作一个 LandAnimal 和一个 WaterAnimal,Cat 将成为 LandAnimal,而 Fish 将成为 WaterAnimal。现在,如果你添加一只鸭子,那么,你必须再次重新定义,因为鸭子是一种 WaterAnimal(他可以摇摆)和一种 LandAnimal(他可以走路)。
我试图找到答案,但很难找到一个好的答案。 可能这个问题是众所周知的,但请帮助我。 我无法完成这项工作:
function Animal() {}
function Cat() {}
Animal.prototype.walk = function() { return 'I can walk' }
Animal.prototype.swim = function() { return 'I can swim' }
如果我写:
Cat.prototype = new Animal();
Cat继承了walk和swim方法,那么要让Cat只继承walk方法应该怎么写呢?
您可以分配一个原型对象 (*.prototype) 另一个 Object Literal ({}) 但要小心继承不再正常工作:
function Person() {}
Person.prototype.walk = function() { return 'I can walk' }
Person.prototype.swim = function() { return 'I can swim' }
function Man() {}
// select methods Man gets inherited here
// just assign certain methods from Person.prototype onto Man.prototype
// therefore Man.prototype inherites only walk method
Man.prototype = {
walk: Person.prototype.walk,
// so swim is not passed onto Man.prototype
// swim: Person.prototype.swim
};
var m = new Man();
// this throws an error
// because a object of type Man does not have got a swim method inherited
// m.swim(); Error!
console.log('is false: ', m instanceof Person);
console.log('parent constructor is Object: ', m.__proto__.__proto__.constructor);
但是正如您所看到的,一些检查以确保此对象是什么实例以及它从哪个超级父构造函数继承某些方法无法正常工作,但它们应该可以工作。
所以你最好以正确的方式使用继承:
function Person() {}
Person.prototype.walk = function() { return 'I can walk' }
Person.prototype.swim = function() { return 'I can swim' }
function Man() {}
Man.prototype = Object.create(Person.prototype);
var m = new Man();
// in this way Person gets every method that is assigned onto Person.prototype
// so swim method is available and can be used by objects of type Man now:
m.swim();
console.log('is true: ', m instanceof Person);
console.log('parent constructor is Person: ', m.__proto__.__proto__.constructor);
这样 instanceof 运算符和对超级父构造函数的引用就可以正常工作。通过这种方式,所有方法都立即分配给 Person,但通过引入额外的抽象或父构造函数,这可能是可以避免的。
希望对您有所帮助。
我认为主要问题不是如何让那只猫继承走路而不是摆动:我认为你展示的方式是不可能的,但这里的问题是对继承层次结构的不完全理解。
看,基本上你在说什么:猫是动物,所以他没有继承动物的所有行为是没有意义的。因为如果你说:Animal 被定义为可以 WALK 和 SWING 的人,然后你说:A Cat 是一种 Animal,那么 Cat MUST MUST WALK AND SWING。
我认为您的情况需要重新组织层次结构。也许你可以制作一个 LandAnimal 和一个 WaterAnimal,Cat 将成为 LandAnimal,而 Fish 将成为 WaterAnimal。现在,如果你添加一只鸭子,那么,你必须再次重新定义,因为鸭子是一种 WaterAnimal(他可以摇摆)和一种 LandAnimal(他可以走路)。