天天看點

javascript/js面向對象:原型、繼承概念

1、原型的概念

原型定義: 每個函數都會建立一個prototype屬性,這個屬性是一個對象,包含應該有特定引用類型的執行個體共享的屬性和方法。同時呢,這個prototype屬性對象又是調用構造函數建立的對象的原型。

原型的特點是: 在原型上定義的屬性和方法可以被對象執行個體共享。

javascript/js面向對象:原型、繼承概念

意思就是,在構造函數Person的原型屬性寫方法和屬性,可以被new Person生成的執行個體共享。

深入了解原型的本質:

隻要建立函數,函數就會有一個prototype屬性(指向原型對象),同時,原型對象會有一個constructor屬性(指向與之關聯的構造函數)。

javascript/js面向對象:原型、繼承概念

在定義構造函數時,原型對象預設隻會獲得constructor屬性,其他所有方法都繼承自Object。

構造函數執行個體 :由調用構造函數建立的對象稱為執行個體對象,該執行個體内部[[Prototype]]指針會被指派為構造函數的原型。浏覽器裡以_proto_屬性表現。

!!!注意: 執行個體與構造函數原型直接有直接的關系,但執行個體與構造函數之間沒有直接關系(執行個體對象是由構造函數建立的)。

構造函數、執行個體與原型三者的關系:

javascript/js面向對象:原型、繼承概念

Object.create()可以建立一個新對象,同時傳入的對象參數為其原型。

2、繼承的概念

寄生式組合繼承:

首先回顧下組合繼承:

function Super(name) {
  this.name = name;
  this.colors = ["red", "blue"];
}

Super.prototype.sayName = function() {
  console.log(this.name);
}

function Sub(name, age) {
  //這裡開始盜用構造函數
  Super.call(this, name);
  
  this.age = age;
}

Sub.prototype = new Super();
Sub.prototype.constructor = Sub;
Sub.protype.sayAge = function() {
  console.log(this.age);
}
           

組合式繼承會有缺陷:會出現兩組同樣的父類屬性,一個在sub原型上,一個在sub執行個體上。不信?你可以:

let person1 = new Sub()

分析一下。原因在于super調用了兩次。

寄生式組合繼承通過盜用構造函數繼承屬性,但使用混合式原型鍊繼承方法。思路為:不通過調用父類構造函數給子類原型指派,而是取得父類原型的一個副本。

寄生式組合繼承的基本模式:

原理主要是:把Sub的原型為Super的執行個體,即sub.prototype.prototype=super.prototype

function inherit(sub, super){
  let prototype = object(super.prototype);
  prototype.constructor = sub;
  sub.prototype = prototype;
}
           

将Sub.prototype = new Super(); => inherit(sub, super);即可。

繼續閱讀