国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > JS > 正文

JS繼承與閉包及JS實現(xiàn)繼承的三種方式

2024-05-06 16:40:20
字體:
供稿:網(wǎng)友

前  言

在之前的兩篇博客中,我們詳細(xì)探討了JavaScript OOP中的各種知識點(JS OOP基礎(chǔ)與JS 中This指向詳解 、 成員屬性、靜態(tài)屬性、原型屬性與JS原型鏈)。今天我們來繼續(xù)探討剩余的內(nèi)容吧。

我們都知道,面向?qū)ο蟮娜筇卣?mdash;—封裝、繼承、多態(tài)。 封裝無非就是屬性和方法的私有化,所以我們JS中提供了私有屬性和私有方法。 而JS中并沒有多態(tài),因此我們說JS是一門基于對象的語言,而非面向?qū)ο蟮恼Z言。 那么,面向?qū)ο笕筇卣髦校贘S中最重要的就是繼承了。

一、繼承的基本概念

使用一個子類繼承另一個父類,子類可以自動擁有父類的屬性和方法。

>>>繼承的兩方,發(fā)生在兩個類之間。

所以,所謂的繼承,無非就是讓子類,擁有父類的所有屬性和方法。那么,在JS中,我們要模擬實現(xiàn)這一步,有三種常用的方法可以實現(xiàn)。

分別是:擴(kuò)展Object的prototype實現(xiàn)繼承、使用call和apply實現(xiàn)繼承、使用原型實現(xiàn)繼承。

二、擴(kuò)展Object的prototype實現(xiàn)繼承

擴(kuò)展Object實現(xiàn)繼承的本質(zhì),是我們自己寫了一個方法,將父類的所有屬性和方法通過遍歷循環(huán),逐個復(fù)制給子類。

詳細(xì)步驟如下:

1:定義父類

functionParent(){}

2:定義子類

funtion Son(){}

3:通過原型給Object對象添加一個擴(kuò)展方法。

Object.prototype.customExtend =function(parObj){for(variinparObj){//通過for-in循環(huán),把父類的所有屬性方法,賦值給自己this[i] =parObj[i];}}

4:子類對象調(diào)用擴(kuò)展方法

Son.customExtend(Parent);

三、使用call和apply實現(xiàn)繼承

首先,要使用這種方式顯示繼承,我們再來回顧一下call和apply兩個函數(shù)的作用:

call和apply:通過函數(shù)名調(diào)用方法,強(qiáng)行將函數(shù)中的this指向某個對象;

call寫法:func.call(func的this指向的obj,參數(shù)1,參數(shù)2...);

apply寫法:func.apply(func的this指向的obj,[參數(shù)1,參數(shù)2...]);

那么,我們使用這兩個函數(shù)實現(xiàn)繼承的思路就是:在子類中,使用父類函數(shù)調(diào)用call或apply,并將父類的this,強(qiáng)行綁定為子類的this。 那這樣,父類綁定在this上的屬性和方法,不就順利成章的綁定到子類的this上了嗎?

詳細(xì)步驟如下:

1:定義父類

funtion Parent(){}

2:定義子類

functionSon(){}

3:在子類中通過call方法或者apply方法去調(diào)用父類。

functionSon(){Parent.call(this,....);//將父類函數(shù)中的this,強(qiáng)行綁定為子類的this}

四、使用原型實現(xiàn)繼承

使用原型實現(xiàn)繼承,是比較簡單而且比較好理解的一種,就是將子類的prototype指向父類的對象就可以啦。

詳細(xì)步驟如下:

1:定義父類

functionParent(){}

2:定義子類

functionSon(){}

3:把在子類對象的原型對象聲明為父類的實例。

Son.prototype =newParent();

五、閉包

要理解閉包,首先,我們要了解一下JS中的作用域:

1、JS中的作用域

全局變量:函數(shù)外聲明的變量

局部變量:函數(shù)內(nèi)聲明的變量

在JS中,函數(shù)為唯一的局部作用域,而if、for等其他{}沒有自己的作用域

所以,函數(shù)外不能訪問局部變量。其實,變量在函數(shù)執(zhí)行完畢以后,占用的內(nèi)存就會被釋放。

2、閉包

在概述中,我剛剛提到,面向?qū)ο蟮娜筇卣髦械?ldquo;封裝”,我們可以用函數(shù)的私有屬性來實現(xiàn)。這個私有屬性,其實也就是局部變量。

但是我們都知道,封裝是限制外部的訪問,并不是直接拒絕外部的訪問,那么我們在函數(shù)中私有的屬性,怎么才能在外部訪問呢?答案就是閉包!

JS中,提供了一種"閉包"的概念:在函數(shù)內(nèi)部,定義一個子函數(shù),可以用子函數(shù)訪問父函數(shù)的私有變量。執(zhí)行完操作以后,將子函數(shù)通過return返回。

代碼示例:

functionfunc2(){varnum = 1;functionfunc3(){varsum = num+10;alert(sum);}returnfunc3;}varf =func2();f();

3、閉包的作用:

① 訪問函數(shù)的私有變量;

② 讓函數(shù)的變量始終存在于內(nèi)存中,而不被釋放。

4、閉包的典型應(yīng)用

我們來做這樣一個功能:頁面中有6個li,要求實現(xiàn)點擊每個li,彈出這個li對應(yīng)的序號。

HTML代碼很簡單:

那JS代碼呢?我覺得很大一部分同學(xué)會這樣寫:

varlis = document.getElementsByTagName("li");for(vari=0;ilis[i].onclick=function(){alert("您/點擊了第"+i+"個li!");}

那么,這樣對嗎?不對!!!我們來分析一下:頁面加載的時候,JS代碼會全部執(zhí)行,也就是上面的for循環(huán)在頁面加載完就已經(jīng)執(zhí)行完了!那,這個i就已經(jīng)變成了lis.length。也就是說,你在點擊li的時候,無論點擊第幾個,彈出的都是lis.length。

那么,我們應(yīng)該怎么修改呢?看代碼!

varlis = document.getElementsByTagName("li");for(vari=0;ilis[j].onclick=function(){alert("您/點擊了第"+j+"個li!");}}();}

區(qū)別在哪?明眼人一眼就看穿我們在for循環(huán)外面嵌套了一層自執(zhí)行函數(shù)!這種函數(shù)套函數(shù)的形式,就形成了閉包!

那作用呢?我們剛才強(qiáng)調(diào),閉包的自執(zhí)行函數(shù)會有自己的作用域。在函數(shù)里面的代碼沒有執(zhí)行的時候,自執(zhí)行函數(shù)中的j是不會被釋放掉的!

也就是說,循環(huán)轉(zhuǎn)了6次!生成了6個獨立的函數(shù)空間,每個空間中有自己獨立的j變量,所以最終不會出現(xiàn)所有l(wèi)i點擊都是lis.length的情況!

總結(jié)

以上所述是小編給大家介紹的JS繼承與閉包及JS實現(xiàn)繼承的三種方式,希望對大家有所幫助!


注:相關(guān)教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 大田县| 依兰县| 莎车县| 敖汉旗| 邳州市| 南投县| 金川县| 郴州市| 西青区| 玉田县| 宜都市| 宣化县| 西乡县| 肇庆市| 昭苏县| 长兴县| 台江县| 东乡族自治县| 和龙市| 丹东市| 康定县| 江门市| 重庆市| 措美县| 道孚县| 辽宁省| 阿荣旗| 湘潭市| 鄂托克前旗| 福鼎市| 克什克腾旗| 绥阳县| 恩施市| 丰台区| 昌乐县| 英山县| 永平县| 申扎县| 沂源县| 建昌县| 昔阳县|