溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

好程序員web前端培訓(xùn)分享JavaScript學(xué)習(xí)筆記閉包與繼承

發(fā)布時(shí)間:2020-08-06 23:15:20 來(lái)源:ITPUB博客 閱讀:108 作者:好程序員 欄目:web開發(fā)

  好程序員web 前端培訓(xùn)分享 JavaScript 學(xué)習(xí)筆記閉包與繼承,閉包:閉包是我們函數(shù)的一種高級(jí)使用方式, 在聊閉包之前我們要先回顧一下  函數(shù)

函數(shù)的兩個(gè)階段

  • 我們一直說(shuō)函數(shù)有兩個(gè)階段
  1. 定義階段
  2. 調(diào)用階段
  3. 開辟一個(gè)  存儲(chǔ)空間
  4. 把函數(shù)體內(nèi)的代碼一模一樣的放在這個(gè)空間內(nèi)(不解析變量)
  5.   存儲(chǔ)空間 的地址給函數(shù)名
  6. 按照函數(shù)名的地址找到函數(shù)的  存儲(chǔ)空間
  7. 形參賦值
  8. 預(yù)解析
  9. 將函數(shù)  存儲(chǔ)空間 中的代碼拿出來(lái)執(zhí)行(才解析變量)
  10. 按照函數(shù)名的地址找到函數(shù)的  存儲(chǔ)空間
  11. 形參賦值
  12. 預(yù)解析
  13. 在內(nèi)存中開辟一個(gè)  執(zhí)行空間
  14. 將函數(shù)  存儲(chǔ)空間 中的代碼拿出來(lái)在剛剛開辟的  執(zhí)行空間 中執(zhí)行
  15. 執(zhí)行完畢后,內(nèi)存中開辟的  執(zhí)行空間 銷毀

函數(shù)定義階段

函數(shù)調(diào)用階段

重新定義函數(shù)調(diào)用階段

function fn() {

    console.log('我是 fn 函數(shù)')}fn() 

  • 函數(shù)執(zhí)行的時(shí)候會(huì)開辟一個(gè)  執(zhí)行空間 (我們暫且叫他 xxff00
  • console.log('我是 fn 函數(shù)') 這個(gè)代碼就是在 xxff00 這個(gè)空間中執(zhí)行
  • 代碼執(zhí)行完畢以后,這個(gè) xxff00 空間就銷毀了
  • 每一個(gè)函數(shù)會(huì)有一個(gè)  存儲(chǔ)空間
  • 但是每一次調(diào)用都會(huì)生成一個(gè)完全不一樣的  執(zhí)行空間
  • 并且  執(zhí)行空間 會(huì)在函數(shù)執(zhí)行完畢后就銷毀了,但是  存儲(chǔ)空間 不會(huì)
  • 那么這個(gè)函數(shù)空間執(zhí)行完畢就銷毀了,還有什么意義呢?
  • 我們可以有一些辦法讓這個(gè)空間  不銷毀
  • 閉包 ,就是要利用這個(gè)  不銷毀的執(zhí)行空間
  • 函數(shù)的  執(zhí)行空間 會(huì)在函數(shù)執(zhí)行完畢之后銷毀
  • 但是,一旦函數(shù)內(nèi)部返回了一個(gè)  引用數(shù)據(jù)類型 ,并且  在函數(shù)外部有變量接受 的情況下
  • 那么這個(gè)函數(shù)  執(zhí)行空間 就不會(huì)銷毀了

函數(shù)執(zhí)行空間

函數(shù)執(zhí)行空間不銷毀

function fn() {

    const obj  = {

       name : 'Jack',

       age : 18,

       gender : '男'

   }

    return obj} const o  = fn()

  • 函數(shù)執(zhí)行的時(shí)候,會(huì)生成一個(gè)函數(shù)  執(zhí)行空間 (我們暫且叫他 xxff00
  • 代碼在 xxff00 空間中執(zhí)行
  •  xxff00 這個(gè)空間中聲名了一個(gè) 對(duì)象空間(xxff11
  •  xxff00 這個(gè)執(zhí)行空間把 xxff11 這個(gè)對(duì)象地址返回了
  • 函數(shù)外部 0 接受的是一個(gè)對(duì)象的地址沒(méi)錯(cuò)
  • 但是是一個(gè)在 xxff00 函數(shù)執(zhí)行空間中的 xxff11 對(duì)象地址
  • 因?yàn)?/span> o 變量一直在和這個(gè)對(duì)象地址關(guān)聯(lián)著,所以 xxff00 這個(gè)空間一直不會(huì)銷毀
  • 等到什么時(shí)候,執(zhí)行一句代碼 o = null
  • 此時(shí), o 變量比在關(guān)聯(lián)在 xxff00 函數(shù)執(zhí)行空間中的 xxff11 對(duì)象地址
  • 那么,這個(gè)時(shí)候函數(shù)執(zhí)行空間 xxff00 就銷毀了
  • 閉包就是利用了這個(gè)函數(shù)執(zhí)行空間不銷毀的邏輯
  • 有幾個(gè)條件組成閉包
  • 閉包的第一個(gè)條件就是利用了不銷毀空間的邏輯
  • 只不過(guò)不是返回一個(gè)  對(duì)象數(shù)據(jù)類型
  • 而是返回一個(gè)  函數(shù)數(shù)據(jù)類型

閉包

不銷毀的空間

function fn() {

     return  function () {}} const f  = fn()

  • f 變量接受的就是一個(gè)  fn的執(zhí)行空間 中的 函數(shù)
  • 涉及到兩個(gè)函數(shù)
  • 內(nèi)部函數(shù)要查看或者使用著外部函數(shù)的變量

內(nèi)部函數(shù)引用外部函數(shù)中的變量

function fn() {

    const num  = 100

    // 這個(gè)函數(shù)給一個(gè)名字,方便寫筆記    return  function a() {

       console.log(num)

   }} const f  = fn()

  • fn() 的時(shí)候會(huì)生成一個(gè) xxff00 的執(zhí)行空間
  •  xxff00 這個(gè)執(zhí)行空間內(nèi)部,定義了一個(gè) a 函數(shù)的  存儲(chǔ)空間xxff11
  • 全局 f 變量接受的就是 xxff00 里面的 xxff11
  • 所以 xxff00 就是不會(huì)銷毀的空間
  • 因?yàn)?/span> xxff00 不會(huì)銷毀,所以,定義再里面的變量 num 也不會(huì)銷毀
  • 將來(lái) f() 的時(shí)候,就能訪問(wèn)到 num 變量
  • 為什么要叫做特點(diǎn),就是因?yàn)樗拿恳粋€(gè)點(diǎn)都是優(yōu)點(diǎn)同時(shí)也是缺點(diǎn)

閉包的特點(diǎn)

  1. 作用域空間不銷毀
  • 優(yōu)點(diǎn):  因?yàn)椴讳N毀,變量頁(yè)不會(huì)銷毀,增加了變量的生命周期
  • 缺點(diǎn):  因?yàn)椴讳N毀,會(huì)一直占用內(nèi)存,多了以后就會(huì)導(dǎo)致內(nèi)存溢出

 

  1. 可以利用閉包訪問(wèn)再一個(gè)函數(shù)外部訪問(wèn)函數(shù)內(nèi)部的變量
  • 優(yōu)點(diǎn):  可以再函數(shù)外部訪問(wèn)內(nèi)部數(shù)據(jù)
  • 缺點(diǎn):  必須要時(shí)刻保持引用,導(dǎo)致函數(shù)執(zhí)行棧不被銷毀

 

  1. 保護(hù)私有變量
  • 優(yōu)點(diǎn):  可以把一些變量放在函數(shù)里面,不會(huì)污染全局
  • 缺點(diǎn):  要利用閉包函數(shù)才能訪問(wèn),不是很方便
  • 有一個(gè) A 函數(shù),再 A 函數(shù)內(nèi)部返回一個(gè) B 函數(shù)
  •  A 函數(shù)外部有變量引用這個(gè) B 函數(shù)
  • B 函數(shù)內(nèi)部訪問(wèn)著 A 函數(shù)內(nèi)部的私有變量
  • 以上三個(gè)條件缺一不可
  • 繼承是和構(gòu)造函數(shù)相關(guān)的一個(gè)應(yīng)用
  • 是指, 讓一個(gè)構(gòu)造函數(shù)去繼承另一個(gè)構(gòu)造函數(shù)的屬性和方法
  • 所以繼承一定出現(xiàn)在  兩個(gè)構(gòu)造函數(shù)之間
  • 我們之前說(shuō),構(gòu)造函數(shù)(類)是對(duì)一類行為的描述
  • 那么我們類這個(gè)概念其實(shí)也很抽象
  • 比如:
  • 我們說(shuō)  國(guó)光 /  富士 都是 蘋果的品種,那么我們就可以寫一個(gè)  蘋果類 來(lái)實(shí)例化很多品種出來(lái)
  •   蘋果 /   這些東西都是水果的一種,那么我們就可以寫一個(gè)  水果類
  • 說(shuō)過(guò)的統(tǒng)一特點(diǎn)就是   /  水分大 ,而不同的水果有不同的特征
  • 那么我們就可以讓  蘋果類 來(lái)繼承  水果類 的內(nèi)容,然后再用  水果類 去實(shí)例化對(duì)象
  • 那么實(shí)例化出來(lái)的就不光有  蘋果類 的屬性和方法,還有  水果類 的屬性和方法
  • 其實(shí)說(shuō)到底,到底什么是繼承
  • 我們之前說(shuō),在我們書寫構(gòu)造函數(shù)的時(shí)候,為了解決一個(gè)函數(shù)重復(fù)出現(xiàn)的問(wèn)題
  • 我們把構(gòu)造函數(shù)的  方法 寫在了 prototype 上

閉包概念(熟讀并背誦全文)

繼承

一個(gè)小例子

繼承的作用

好程序員web前端培訓(xùn)分享JavaScript學(xué)習(xí)筆記閉包與繼承

  • 這樣,每一個(gè)實(shí)例使用的方法就都是來(lái)自構(gòu)造函數(shù)的 prototype 上
  • 就避免了函數(shù)重復(fù)出現(xiàn)占用內(nèi)存得到情況
  • 那么,如果兩個(gè)構(gòu)造函數(shù)的 prototype 中有一樣的方法呢,是不是也是一種浪費(fèi)
  • 所以我們把構(gòu)造函數(shù)? prototype 中的公共的方法再次盡心提取

    好程序員web前端培訓(xùn)分享JavaScript學(xué)習(xí)筆記閉包與繼承

  • 我們準(zhǔn)備一個(gè)更公共的構(gòu)造函數(shù),讓構(gòu)造函數(shù)的 __proto__ 指向這個(gè)公共的構(gòu)造函數(shù)的 prototype
  • 我們有一些常見的繼承方式來(lái)實(shí)現(xiàn)和達(dá)到繼承的效果
  • 我們先準(zhǔn)備一個(gè)父類(也就是要讓別的構(gòu)造函數(shù)使用我這個(gè)構(gòu)造函數(shù)的屬性和方法)

常見的繼承方式

function Person() {

     this.name  = 'Jack'}Person.prototype.sayHi  =  function () {

    cosnole.log('hello')}

  • 這個(gè) Person 構(gòu)造函數(shù)為父類
  • 讓其他的構(gòu)造函數(shù)來(lái)繼承他
  • 當(dāng)別的構(gòu)造函數(shù)能夠使用他的屬性和方法的時(shí)候,就達(dá)到了繼承的效果
  • 原型繼承,就是在本身的原型鏈上加一層結(jié)構(gòu)

原型繼承

function Student() {}Student.prototype  =  new Person()

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

  • 把父類構(gòu)造函數(shù)體借用過(guò)來(lái)使用一下而已

function Student() {

    Person.call( this)}

組合繼承

  • 就是把  原型繼承 和  借用構(gòu)造函數(shù)繼承 兩個(gè)方式組合在一起

function Student() {

    Person.call( this)}Student.prototype  =  new Person

ES6 的繼承

  • es6 的繼承很容易,而且是固定語(yǔ)法
    // 下面表示創(chuàng)造一個(gè) Student 類,繼承自 Person 類

class Student  extends Person {

    constructor () {

         // 必須在 constructor 里面執(zhí)行一下 super() 完成繼承          super()

    }}

  • 這樣就繼承成功了
向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI