JavaScript 的幾種繼承方式

JavaScript 的幾種繼承方式

  • 原型鏈繼承
  • 構造函數繼承
  • 組合繼承 (僞經典繼承)
  • 原型式繼承
  • 寄生式繼承
  • 寄生組合式繼承
  • ES6 extend 繼承

1, 原型鏈繼承

原理是將父對象的屬性和方法經過prototype進行引用javascript

function people() {
    this.flag = true;
    this.func = function() {
        console.log("this is people func");
    }
}
function boy() {
    this.sex = "boy";
}
boy.prototype = new people();
var peo1 = new boy();
console.log( peo1.flag );     // true
console.log( peo1.func() );   // this is people func
console.log( peo1.sex );      // boy

缺點:java

  • 實例對象的屬性被共享
  • 沒法向父對象的方法傳遞參數

2, 構造函數繼承

構造函數繼承主要在繼承對象中使用 call()、apply() 完成。es6

function people(name) {
    this.name = name || "xiaoming";
}

// 對people進行繼承
function boy() {
    people.call(this, "wangming");
    this.age = 18;
}
var peo1 = new boy();
console.log( peo1.name ); //wangming
console.log( peo1.age ); //18

缺點:app

  • 函數沒法複用
  • 父對象的方法對子類不可見

3, 組合繼承 (僞經典繼承)

結合原型鏈和構造函數繼承。思路是利用原型鏈繼承原型上的屬性和方法,構造函數繼承實例的屬性,也就是父對象本身的屬性。函數

function people(name) {
    this.name = name || "xiaoming";
}
people.prototype.sayName = function() {
    alert(this.name);
}

//構造函數繼承屬性
function boy(name, age) {
    people.call(this, name);
    
    this.age = age || 18;
}
//原型鏈繼承方法
boy.prototype = new people();
boy.prototype.sayAge = function() {
    alert(this.age);
}

var peo1 = new boy("zhangsan", 22);
peo1.sayName();  // zhangsan
peo1.sayAge();   // 22

由於結合了原型鏈和構造函數繼承的優勢,成爲了最經常使用的繼承模式。但也有缺點,就是調用了兩次父對象的構造函數。(使用call時一次,使用new又是一次)this

4,原型式繼承

這種繼承模式的思路是建立一個基本對象,裏面包含通用的屬性、函數。經過特定函數建立實例。prototype

function object(o) {
        function F() {}
        F.prototype = o;
        return new F();
    }

利用該函數建立的實例對象實際上是原來基本對象的副本。ES5中新增了Object.create()對其進行規範。兼容IE9+。code

var person = {
    name: "Neo",
    sayName: function() {
        console.log(this.name);
    }
}
var obj = Object.create(person);
obj.name = "test";
obj.sayName();    // test
person.sayName(); // Neo

5,寄生式繼承

寄生式與原型式相關。用一個函數封裝繼承過程,相似於工廠模式。對象

function createAnother( obj ) {
    var clone = Object.create(obj);
    clone.sayName = function() {
        alert(this.name);
    }
    return clone;
}
var people = {
    name: "test"
}
var boy = createAnother(people);
boy.sayName(); // test

6,寄生組合式繼承

寄生式繼承與組合式繼承,實現一種最理想的繼承模式。繼承

function inheritPrototype( subItem, superItem ) {
    var clone = Object.create(superItem.prototype);
    clone.constructor = subItem;
    subItem.prototype = clone;
}
function superItem(name) {
    this.name = name;
}
superItem.prototype.sayName = function() {
    alert(this.name);
}

function subItem(name, age) {
    superItem.call(this, name);
    this.age = age || 18;
}
inheritPrototype(subItem, superItem);

var obj = new subItem("leo");
obj.sayName();    //leo

7, ES6 extend 繼承

利用ES6提供的類繼承關鍵字extends實現。

class People {
    constructor(){
        this.name = "leo";
    }
    sayName(){
        alert(this.name);
    }
}
class Boy extends People{
    constructor(props){
        super(props);
        this.name = "li"
    }
}
var peo1 = new People();
var peo2 = new Boy();

peo1.sayName(); // leo
peo2.sayName(); // li

以上就是我所總結的7中繼承方式

相關文章
相關標籤/搜索