【问题标题】:Javascript's prototype, how to inherit a class?Javascript的原型,如何继承一个类?
【发布时间】:2015-07-29 20:42:10
【问题描述】:

我需要 Javascript 中两个类之间的继承关系。 我喜欢在构造函数中声明属性;对于方法,原型:

function Animal(){
   this.someProperty = 'someProperty';
   this.init();
}
Animal.prototype = {
   init : function(){ }
   anotherMethod : function(){ }
}

我认为声明这样的方法比:

 Animal.prototype.init = function(){ }
 Animal.prototype.anotherMethod = function(){}

但是当我需要从另一个类继承某个类时,我找不到按照我的方式去做的方法。这不起作用:

  Cat.prototype = new Animal();
  Cat.prototype = {
      init : function(){ }
  }

我知道我可以像下一个那样做:

  Cat.prototype = new Animal();
  Cat.prototype.init = function(){ }
  Cat.prototype.anotherMethod = function(){ }

但是,有没有办法按照我的方式去做?

【问题讨论】:

标签: javascript oop inheritance


【解决方案1】:

查看一些继承方法以使继承工作:

第一个链接中的示例可以总结一下,类似但略有不同:

function Mammal(name){ 
    this.name=name;
    this.offspring=[];
} 
Mammal.prototype.haveABaby=function(){ 
    var newBaby=new Mammal("Baby "+this.name);
    this.offspring.push(newBaby);
    return newBaby;
} 
Mammal.prototype.toString=function(){ 
    return '[Mammal "'+this.name+'"]';
} 


Cat.prototype = new Mammal();        // Here's where the inheritance occurs 
Cat.prototype.constructor=Cat;       // Otherwise instances of Cat would have a constructor of Mammal 
function Cat(name){ 
    this.name=name;
} 
Cat.prototype.toString=function(){ 
    return '[Cat "'+this.name+'"]';
} 


var someAnimal = new Mammal('Mr. Biggles');
var myPet = new Cat('Felix');
alert('someAnimal is '+someAnimal);   // results in 'someAnimal is [Mammal "Mr. Biggles"]' 
alert('myPet is '+myPet);             // results in 'myPet is [Cat "Felix"]' 

myPet.haveABaby();                    // calls a method inherited from Mammal 
alert(myPet.offspring.length);        // shows that the cat has one baby now 
alert(myPet.offspring[0]);

有一些框架专注于原型继承,可以为您管理一些管道。

【讨论】:

    【解决方案2】:

    如果您想保持与您当前使用的语法相似的语法,您应该扩展原型而不是替换它。

    例如,对于 lodash,您可以像这样使用 assign

    _.assign(Cat.prototype, {
       init : function(){ }}
    );
    

    【讨论】:

      【解决方案3】:

      这样做

        Cat.prototype = new Animal();
        Cat.prototype = {
            init : function(){ }
        }
      

      你覆盖了第一个声明,所以它不会得到 Animal 方法。

      在 javascript 中,您只能使用原型进行继承

        Cat.prototype = new Animal();
        Cat.prototype.init = function(){ }
      

      【讨论】:

        【解决方案4】:

        首先,使用Object.create设置继承

        接下来,如果您想使用一个 Object 来扩展另一个 Object 您可以使用Object.getOwnPropertyDescriptorObject.defineProperty 将其属性描述符复制到另一个上,例如

        function copyAtoB(A, B) {
            var d = Object.getOwnPropertyNames(A),
                i;
            for (i = 0; i < d.length; ++i)
                Object.defineProperty(
                    B,
                    d[i],
                    Object.getOwnPropertyDescriptor(A, d[i])
                );
            return B;
        }
        
        
        function Animal() {
            this.isAnimal = true;
            // etc
        }
        Animal.prototype = Object.create(null); // Animal doesn't inherit from anything
        copyAtoB({
            foo: function () { console.log('foo'); }
        }, Animal.prototype);
        
        
        function Cat() {
            Animal.call(this); // the Animal constructor helps build cats
            this.isCat = true;
            // etc
        }
        Cat.prototype = Object.create(Animal.prototype); // Cat inherits from Animal
        copyAtoB({
            bar: function () { console.log('bar'); }
        }, Cat.prototype);
        

        现在我们有

        var cat = new Cat();
        cat.isCat; // true
        cat.isAnimal; // true
        cat.foo(); // logs "foo"
        cat.bar(); // logs "bar"
        

        【讨论】:

          【解决方案5】:

          您可以使用扩展方法。

          Cat.prototype.extend({
            init : function(){ }
          }, new Animal());
          
          function extend(destination, source) {
            Object.keys(source).forEach(function (key) {
              if(typeof destination[key] === 'undefined') {
                destination[key] = source[key]    
              }
            }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2010-09-28
            • 2018-02-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多