99re热这里只有精品视频,7777色鬼xxxx欧美色妇,国产成人精品一区二三区在线观看,内射爽无广熟女亚洲,精品人妻av一区二区三区

JavaScript對象繼承一瞥

2018-06-16 20:27 更新

js創(chuàng)建之初,正值java大行其道,面向?qū)ο缶幊檀猴L正盛,js借鑒了java的對象機制,但僅是看起來像,也就是js的構(gòu)造函數(shù),如下:

function People(age) {
	this.age = age;
	this.getAge = function (){return this.age};
}

var p1 = new People(20);//People的實例1
var p2 = new People(40);//People的實例2

上面的代碼很像java了,通過new constructor()的方式,可以創(chuàng)建多個實例。

但上面代碼問題是getAge方法會在每個People的實例中存在,如果實例多的話,會浪費很多空間,js采用了犧牲時間,獲取空間的方法,js引入了原型理念,將方法放入原型中:

function People(age) {
	this.age = age
}

People.prototype.getAge = function () {return this.age};

本文就來總結(jié)下,如何使用構(gòu)造函數(shù)來實現(xiàn)繼承。

場景

我們假設(shè)我們有一個父構(gòu)造函數(shù)People和子構(gòu)造函數(shù)Student,People有一個屬性age和一個方法getAge,Student有一個屬性num和getNum。

function People(age) {
	this.age = age;
}
People.prototype.getAge = function (){return this.age;};

function Student(num) {
	this.num = num;
}
Student.prototype.getNum = function () {return this.num;};

我們要實現(xiàn)是Student繼承People,這在js里可要費一番力氣了。

默認模式

我們可以利用js的原型機制,將子構(gòu)造函數(shù)的原型屬性設(shè)置為父構(gòu)造函數(shù)的實例,這是js中比較常用的方式:

function Student(num) {
	this.num = num;
}

Student.prototype = new People();

Student.prototype.getNum = function () {return this.num;};

var stu1 = new Student('123');

這樣做其實基本實現(xiàn)了我們的需求,但如果深入思考上面的方式,其實有幾個缺點:

  1. 子類無法繼承父類的實例屬性
  2. 會將父類的實例屬性,擴展到子類的原型上
  3. 修改了子類的原型屬性,會導(dǎo)致在stu1上獲取constructor屬性為People,而不是Student

哦?。?!

借用構(gòu)造函數(shù)

先來看看如何解決第一個問題,我們可以巧用js的call方法,如果你還不知道這個方法,請移步這里。

function Student(age, num) {
	People.call(this, age);
	this.num = num;
}

我們在子構(gòu)造函數(shù)內(nèi)部,借用父構(gòu)造函數(shù),這樣就巧妙地在子類中繼承了父類的實例化屬性。這其實類似java的super關(guān)鍵字。

共享原型

再來看看如何解決第二個問題,解決這個問題,其實我們可以將子構(gòu)造函數(shù)的原型更改為父構(gòu)造函數(shù)的原型,而不是父構(gòu)造函數(shù)的實例。

Student.prototype = People.prototype;

這樣就不會將父構(gòu)造函數(shù)的實例屬性擴展到子構(gòu)造函數(shù)的原型上了。

但這樣做會導(dǎo)致另一個問題,就是無法再在Student的原型上擴展方法了,因為會擴展同時會擴展到People的原型上。

臨時構(gòu)造函數(shù)

為了解決上面引發(fā)的問題,和第三個問題。我們可以在子構(gòu)造函數(shù)和父構(gòu)造函數(shù)之間,加一層臨時構(gòu)造函數(shù)。

function F() {
}

F.prototype = People.prototype;

Student.prototype = new F();

這樣就可以Student的原型上擴展子構(gòu)造函數(shù)的方法,同時不影響父構(gòu)造函數(shù)的原形了。

在修復(fù)一下constructor屬性就ok啦

Student.prorotype.constructor = Student;

圣杯

我們將上面的幾種方法綜合起來,代碼看起來就像下面這樣子:

//繼承函數(shù)
function inherit(C, P) {
	var F = function (){};
	F.prototype = P.prototype;
	C.prototype = new F();//臨時構(gòu)造函數(shù)

	C.prototype.constructor = C;//修復(fù)constructor
	C.uper = P;//存儲超類
}

function People(age) {
	this.age = age;
}
People.prototype.getAge = function (){return this.age;};

function Student(age, num) {
	Student.uber.call(this, age);
	this.num = num;
}

inherit(Student, People);//繼承父構(gòu)造函數(shù)
Student.prototype.getNum = function () {return this.num;};

總結(jié)

本文大部分內(nèi)容其實出自,《javascript模式》第五章 代碼的復(fù)用模式。記錄下來省的自己每次都要去翻書了,當然主要還是寫給MM看的。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號