AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當(dāng)前位置:首頁(yè) > 科技  > 軟件

JS 常見的 六種繼承方式,你知道幾種?

來(lái)源: 責(zé)編: 時(shí)間:2023-10-30 17:24:03 244觀看
導(dǎo)讀原型鏈繼承原型鏈繼承是比較常見的繼承方式之一,其中涉及的構(gòu)造函數(shù)、原型和實(shí)例,三者之間存在著一定的關(guān)系,即每一個(gè)構(gòu)造函數(shù)都有一個(gè)原型對(duì)象,原型對(duì)象又包含一個(gè)指向構(gòu)造函數(shù)的指針,而實(shí)例則包含一個(gè)原型對(duì)象的指針。例

原型鏈繼承

原型鏈繼承是比較常見的繼承方式之一,其中涉及的構(gòu)造函數(shù)、原型和實(shí)例,三者之間存在著一定的關(guān)系,即每一個(gè)構(gòu)造函數(shù)都有一個(gè)原型對(duì)象,原型對(duì)象又包含一個(gè)指向構(gòu)造函數(shù)的指針,而實(shí)例則包含一個(gè)原型對(duì)象的指針。例如:CH428資訊網(wǎng)——每日最新資訊28at.com

function Parent1() {    this.name = 'parent1';    this.play = [1, 2, 3]}function Child1() {    this.type = 'child2';}Child1.prototype = new Parent1();console.log(new Child1());

上面的代碼其實(shí)有一個(gè)潛在的問(wèn)題,例如:CH428資訊網(wǎng)——每日最新資訊28at.com

var s1 = new Child1();var s2 = new Child1();s1.play.push(4);console.log(s1.play);console.log(s2.play);

執(zhí)行結(jié)果如下:CH428資訊網(wǎng)——每日最新資訊28at.com

當(dāng)我修改了s1的play屬性的時(shí)候,s2的play屬性也跟著變了,因?yàn)閮蓚€(gè)實(shí)例使用的是同一個(gè)原型對(duì)象。它們的內(nèi)存空間是共享的,當(dāng)一個(gè)發(fā)生變化的時(shí)候,另外一個(gè)也隨之進(jìn)行了變化,這就是使用原型鏈繼承方式的一個(gè)缺點(diǎn)。CH428資訊網(wǎng)——每日最新資訊28at.com

構(gòu)造函數(shù)繼承(借助 call)

function Parent1(){    this.name = 'parent1';}Parent1.prototype.getName = function () {    return this.name;}function Child1(){    Parent1.call(this);    this.type = 'child1'}let child = new Child1();console.log(child);  // 沒(méi)問(wèn)題console.log(child.getName());  // 會(huì)報(bào)錯(cuò)-----------------------------------?著作權(quán)歸作者所有:來(lái)自51CTO博客作者前端面試題庫(kù)助手的原創(chuàng)作品,請(qǐng)聯(lián)系作者獲取轉(zhuǎn)載授權(quán),否則將追究法律責(zé)任JS 常見的 6 種繼承方式https://blog.51cto.com/u_14627797/8080448

運(yùn)行結(jié)果如下:CH428資訊網(wǎng)——每日最新資訊28at.com

除了 Child1 的屬性 type 之外,也繼承了 Parent1 的屬性 name。這樣寫的時(shí)候子類雖然能夠拿到父類的屬性值,解決了第一種繼承方式的弊端,但問(wèn)題是,父類原型對(duì)象中一旦存在父類之前自己定義的方法,那么子類將無(wú)法繼承這些方法。CH428資訊網(wǎng)——每日最新資訊28at.com

因此構(gòu)造函數(shù)實(shí)現(xiàn)繼承的優(yōu)缺點(diǎn),它使父類的引用屬性不會(huì)被共享,優(yōu)化了第一種繼承方式的弊端;但是隨之而來(lái)的缺點(diǎn)也比較明顯——只能繼承父類的實(shí)例屬性和方法,不能繼承原型屬性或者方法。CH428資訊網(wǎng)——每日最新資訊28at.com

組合繼承(前兩種組合)

這種方式結(jié)合了前兩種繼承方式的優(yōu)缺點(diǎn),結(jié)合起來(lái)的繼承,代碼如下:CH428資訊網(wǎng)——每日最新資訊28at.com

function Parent3 () {    this.name = 'parent3';    this.play = [1, 2, 3];  }  Parent3.prototype.getName = function () {    return this.name;  }  function Child3() {    // 第二次調(diào)用 Parent3()    Parent3.call(this);    this.type = 'child3';  }  // 第一次調(diào)用 Parent3()  Child3.prototype = new Parent3();  // 手動(dòng)掛上構(gòu)造器,指向自己的構(gòu)造函數(shù)  Child3.prototype.constructor = Child3;  var s3 = new Child3();  var s4 = new Child3();  s3.play.push(4);  console.log(s3.play);  // 不互相影響  console.log(s4.play);  console.log(s3.getName()); // 正常輸出'parent3'  console.log(s4.getName()); // 正常輸出'parent3'

結(jié)果如下:CH428資訊網(wǎng)——每日最新資訊28at.com

之前方法一和方法二的問(wèn)題都得以解決,但是這里又增加了一個(gè)新問(wèn)題:通過(guò)注釋我們可以看到 Parent3 執(zhí)行了兩次,第一次是改變Child3 的 prototype 的時(shí)候,第二次是通過(guò) call 方法調(diào)用 Parent3 的時(shí)候,那么 Parent3 多構(gòu)造一次就多進(jìn)行了一次性能開銷。CH428資訊網(wǎng)——每日最新資訊28at.com

原型式繼承

ES5 里面的 Object.create 方法,這個(gè)方法接收兩個(gè)參數(shù):一是用作新對(duì)象原型的對(duì)象、二是為新對(duì)象定義額外屬性的對(duì)象(可選參數(shù))。CH428資訊網(wǎng)——每日最新資訊28at.com


CH428資訊網(wǎng)——每日最新資訊28at.com

let parent4 = {    name: "parent4",    friends: ["p1", "p2", "p3"],    getName: function() {        return this.name;    }};let person4 = Object.create(parent4);person4.name = "tom";person4.friends.push("jerry");let person5 = Object.create(parent4);person5.friends.push("lucy");console.log(person4.name);console.log(person4.name === person4.getName());console.log(person5.name);console.log(person4.friends);console.log(person5.friends);

執(zhí)行結(jié)果如下:CH428資訊網(wǎng)——每日最新資訊28at.com

通過(guò) Object.create 這個(gè)方法可以實(shí)現(xiàn)普通對(duì)象的繼承,不僅僅能繼承屬性,同樣也可以繼承 getName 的方法。前三個(gè)輸出都是正常的,最后兩個(gè)輸出結(jié)果一致是因?yàn)镺bject.create 方法是可以為一些對(duì)象實(shí)現(xiàn)淺拷貝的,那么關(guān)于這種繼承方式的缺點(diǎn)也很明顯,多個(gè)實(shí)例的引用類型屬性指向相同的內(nèi)存。CH428資訊網(wǎng)——每日最新資訊28at.com

寄生式繼承

使用原型式繼承可以獲得一份目標(biāo)對(duì)象的淺拷貝,然后利用這個(gè)淺拷貝的能力再進(jìn)行增強(qiáng),添加一些方法,這樣的繼承方式就叫作寄生式繼承。CH428資訊網(wǎng)——每日最新資訊28at.com

雖然其優(yōu)缺點(diǎn)和原型式繼承一樣,但是對(duì)于普通對(duì)象的繼承方式來(lái)說(shuō),寄生式繼承相比于原型式繼承,還是在父類基礎(chǔ)上添加了更多的方法。實(shí)現(xiàn)如下:CH428資訊網(wǎng)——每日最新資訊28at.com

let parent5 = {    name: "parent5",    friends: ["p1", "p2", "p3"],    getName: function() {        return this.name;    }};function clone(original) {    let clone = Object.create(original);    clone.getFriends = function() {        return this.friends;    };    return clone;}let person5 = clone(parent5);console.log(person5.getName());console.log(person5.getFriends());

輸出結(jié)果如下:CH428資訊網(wǎng)——每日最新資訊28at.com

從最后的輸出結(jié)果中可以看到,person5 通過(guò) clone 的方法,增加了 getFriends 的方法,從而使 person5 這個(gè)普通對(duì)象在繼承過(guò)程中又增加了一個(gè)方法,這樣的繼承方式就是寄生式繼承。CH428資訊網(wǎng)——每日最新資訊28at.com

寄生組合式繼承

結(jié)合第四種中提及的繼承方式,解決普通對(duì)象的繼承問(wèn)題的 Object.create 方法,我們?cè)谇懊孢@幾種繼承方式的優(yōu)缺點(diǎn)基礎(chǔ)上進(jìn)行改造,得出了寄生組合式的繼承方式,這也是所有繼承方式里面相對(duì)最優(yōu)的繼承方式,代碼如下:CH428資訊網(wǎng)——每日最新資訊28at.com

function clone (parent, child) {    // 這里改用 Object.create 就可以減少組合繼承中多進(jìn)行一次構(gòu)造的過(guò)程    child.prototype = Object.create(parent.prototype);    child.prototype.constructor = child;}function Parent6() {    this.name = 'parent6';    this.play = [1, 2, 3];}Parent6.prototype.getName = function () {    return this.name;}function Child6() {    Parent6.call(this);    this.friends = 'child5';}clone(Parent6, Child6);    Child6.prototype.getFriends = function () {    return this.friends;}let person6 = new Child6();console.log(person6);console.log(person6.getName());console.log(person6.getFriends());-----------------------------------?著作權(quán)歸作者所有:來(lái)自51CTO博客作者前端面試題庫(kù)助手的原創(chuàng)作品,請(qǐng)聯(lián)系作者獲取轉(zhuǎn)載授權(quán),否則將追究法律責(zé)任JS 常見的 6 種繼承方式https://blog.51cto.com/u_14627797/8080448

執(zhí)行結(jié)果如下:CH428資訊網(wǎng)——每日最新資訊28at.com

這種寄生組合式繼承方式,基本可以解決前幾種繼承方式的缺點(diǎn),較好地實(shí)現(xiàn)了繼承想要的結(jié)果,同時(shí)也減少了構(gòu)造次數(shù),減少了性能的開銷。整體看下來(lái),這六種繼承方式中,寄生組合式繼承是這六種里面最優(yōu)的繼承方式。CH428資訊網(wǎng)——每日最新資訊28at.com

ES6的extends關(guān)鍵字實(shí)現(xiàn)邏輯

ES6提供了extends語(yǔ)法糖,使用關(guān)鍵字很容易實(shí)現(xiàn)JavaScript的繼承,先看一下extends使用方法。CH428資訊網(wǎng)——每日最新資訊28at.com

class Person {  constructor(name) {    this.name = name  }  // 原型方法  // 即 Person.prototype.getName = function() { }  // 下面可以簡(jiǎn)寫為 getName() {...}  getName = function () {    console.log('Person:', this.name)  }}class Gamer extends Person {  constructor(name, age) {    // 子類中存在構(gòu)造函數(shù),則需要在使用“this”之前首先調(diào)用 super()。    super(name)    this.age = age  }}const asuna = new Gamer('Asuna', 20)asuna.getName() // 成功訪問(wèn)到父類的方法

使用babel將ES6 的代碼編譯成 ES5,代碼如下:CH428資訊網(wǎng)——每日最新資訊28at.com

function _possibleConstructorReturn (self, call) { 		// ...		return call && (typeof call === 'object' || typeof call === 'function') ? call : self; }function _inherits (subClass, superClass) {     // 這里可以看到	subClass.prototype = Object.create(superClass && superClass.prototype, { 		constructor: { 			value: subClass, 			enumerable: false, 			writable: true, 			configurable: true 		} 	}); 	if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }var Parent = function Parent () {	// 驗(yàn)證是否是 Parent 構(gòu)造出來(lái)的 this	_classCallCheck(this, Parent);};var Child = (function (_Parent) {	_inherits(Child, _Parent);	function Child () {		_classCallCheck(this, Child);		return _possibleConstructorReturn(this, (Child.__proto__ || Object.getPrototypeOf(Child)).apply(this, arguments));}	return Child;}(Parent));

本文鏈接:http://www.tebozhan.com/showinfo-26-15860-0.htmlJS 常見的 六種繼承方式,你知道幾種?

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: 了解Springboot起步依賴及其實(shí)現(xiàn)原理

下一篇: 使用Frida在Windows中攔截C++函數(shù)

標(biāo)簽:
  • 熱門焦點(diǎn)
Top