繼承

  • 構(gòu)造函數(shù)、原型和實(shí)例的關(guān)系:

每個(gè)構(gòu)造函數(shù)都有其對(duì)應(yīng)的原型對(duì)象;
每個(gè)原型對(duì)象都有一個(gè)構(gòu)造函數(shù)指針constructor指向其構(gòu)造函數(shù);
每個(gè)實(shí)例都包含一個(gè)內(nèi)部指針[[prototype]],指向構(gòu)造函數(shù)的原型對(duì)象;

我們創(chuàng)建一個(gè)Person構(gòu)造函數(shù)和一個(gè)Student構(gòu)造函數(shù),如下:

function Person(){
  this.name = "張三",
  this.hobby=["游泳","看書"]
}
Person.prototype.sayName=function(){return this.name}

function Student(){
  this.needStudy = true
}
Student.prototype.getStudy=function(){return this.needStudy}

Person構(gòu)造函數(shù)的原型屬性有sayName,實(shí)例屬性有name和hobby。Student的原型屬性有g(shù)etStudy,實(shí)例屬性有needStudy。
用結(jié)構(gòu)圖展示構(gòu)造函數(shù)、原型對(duì)象和實(shí)例的關(guān)系如下:


Person構(gòu)造函數(shù).png

Student構(gòu)造函數(shù).png

繼承的實(shí)現(xiàn)

下面講述3種繼承的實(shí)現(xiàn)方法:
原型鏈繼承、借用構(gòu)造函數(shù)繼承、組合繼承。

1.原型鏈繼承

讓Student繼承Person的實(shí)現(xiàn):
令Student的原型對(duì)象等于Person的實(shí)例。

Student.prototype = new Person()
//Student原型上的方法需要重新定義以下,因?yàn)樯厦嬷貙懥薙tudent原型對(duì)象
Student.prototype.getStudy=function(){return this.needStudy}

var stu1 = new Student()

其結(jié)構(gòu)圖如下:


Student與Person的繼承關(guān)系圖.png

原型鏈實(shí)現(xiàn)繼承的本質(zhì):重寫原型對(duì)象。

  • 注意:子類型中定義與超類型同樣的方法名會(huì)覆蓋超類型中的方法。
    如下:
Student.prototype.sayName=function(){return "李四"}

var stu1 = new Student()

stu1.sayName() //"李四"
  • 原型鏈的問題:

1.超類型上定義的實(shí)例屬性會(huì)相互影響,如下:

function Person(){
  this.name = "張三",
  this.hobby=["游泳","看書"]
}
function Student(){
}
Student.prototype = new Person()
var stu1=new Student()
var stu2=new Student()
stu1.hobby.push("聽歌")
console.log(stu1.hobby, stu2.hobby)

上述對(duì)stu1的hobby的改變會(huì)影響到stu2的hobby值。

2.無法向超類型傳遞參數(shù)

function Person(name, hobby){
  this.name = name,
  this.hobby = hobby
}
function Student(){
}
Student.prototype = new Person("張三",["游泳"])
var stu1=new Student()
var stu2=new Student()

如果想在new Student()的時(shí)候傳遞參數(shù)給Person,是無法傳遞的。
為解決以上問題,可以使用借用構(gòu)造函數(shù)方法。

2.借用構(gòu)造函數(shù)繼承
function Person(name,hobby){
  this.name = name,
  this.hobby=hobby
}
Person.prototype.sayName=function(){return this.name}
function Student(name,hobby){
  this.needStudy = true
  Person.call(this,name,hobby)
}
var stu1 = new Student("張三",["看書"])
var stu2 = new Student("李四",["聽歌"])

將超類型中的方法和屬性在子類型中定義一遍。

  • 借用構(gòu)造函數(shù)的問題:

方法都在構(gòu)造函數(shù)中定義,函數(shù)無法實(shí)現(xiàn)復(fù)用;
超類型中的原型方法無法訪問到。

3.組合繼承
function Person(name,hobby){
  this.name = name,
  this.hobby=hobby
}
Person.prototype.sayName=function(){return this.name}
function Student(name,hobby){
  this.needStudy = true
  Person.call(this,name,hobby)
}
Student.prototype = new Person();
Student.prototype.constructor = Student
Student.prototype.getStudy=function(){
  return this.needStudy
}
var stu1 = new Student("張三",["看書"])
var stu2 = new Student("李四",["聽歌"])
  • 組合繼承本質(zhì):

原型鏈繼承共享的屬性和方法,借用構(gòu)造函數(shù)繼承實(shí)例屬性。

總結(jié)

image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容