Skip to content

Latest commit

 

History

History
122 lines (105 loc) · 3.52 KB

继承.md

File metadata and controls

122 lines (105 loc) · 3.52 KB

JavaScript 继承

  下面介绍 4 种常见继承方式:原型继承构造继承组合继承组合寄生式继承。下面是一个父类的声明:

function Animal (name) {
    // 属性
    this.name = name || 'Animal';
    // 实例方法
    this.sleep = function(){
        console.log(this.name + ' 正在睡觉!');
    }
}
// 原型方法
Animal.prototype.eat = function(food) {
  console.log(this.name + ' 正在吃 ' + food);
};

原型链继承

  将父类的实例作为子类的原型。

function Cat(){}

Cat.prototype = new Animal();
Cat.prototype.name = 'cat';   //如果要为原型添加属性,必须一个个添加
Cat.prototype.constructor = Cat; // 修复构造函数指向

// Test Code
var cat = new Cat();
console.log(cat.name);              // cat
cat.sleep();                        // cat 正在睡觉
cat.eat('fish');                    // cat 正在吃 fish
console.log(cat instanceof Animal); // true 
console.log(cat instanceof Cat);    // true

构造继承

  使用父类的构造函数来增强子类实例(没用到原型),但是这样只是借用了构造函数,没有构造我们想要的原型链。

function Cat(name){
    Animal.call(this,name);
    this.name = name || 'Tom';
}

// Test Code
var cat = new Cat("cat");
console.log(cat.name);              // cat
cat.sleep();                        // cat 正在睡觉
cat.eat('fish');                    // 找不到 eat 函数
console.log(cat instanceof Animal); // false
console.log(cat instanceof Cat);    // true

组合继承

  使用上述两种方法的组合,唯一缺点就是调用了两次父类构造函数

function Cat(name){
    Animal.call(this,name);
    this.name = name || 'Tom';
}
Cat.prototype = new Animal();
Cat.prototype.constructor = Cat; // 修复构造函数指向

// Test Code
var cat = new Cat("cat");
console.log(cat.name);              // cat
cat.sleep();                        // cat 正在睡觉
cat.eat('fish');                    // cat 正在吃 fish
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat);    // true

组合寄生式继承

  通过一个中介函数temp(),拷贝 Animal 类的原型。其他实现与组合继承相同。

function Cat(name){
    Animal.call(this,name);
}
var temp = function(){};
temp.prototype = Animal.prototype;
Cat.prototype = new temp();
Cat.prototype.constructor = Cat;   // 修复构造函数指向

// Test Code
var cat = new Cat("cat");
console.log(cat.name);              // cat
cat.sleep();                        // cat 正在睡觉
cat.eat('fish');                    // cat 正在吃 fish
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat);    // true

  使用Object.create()更简洁地进行原型复制。

function Cat(name){
    Animal.call(this,name);
}

/*
var temp = function(){};
temp.prototype = Animal.prototype;
Cat.prototype = new temp();
*/
Cat.prototype = Object.create(Animal.prototype); // 这行代码的作用即为上述三行代码
Cat.prototype.constructor = Cat;                 // 修复构造函数指向

总结

  • 类属性用 this 界定
  • 类方法用 prototype 对象界定
  • 继承属性,使用 call() 函数传递 this 对象和构造参数
  • 继承方法,使用 Object.create() 连接父类和子类的原型
  • 始终将子类构造函数设置成自身