中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript中的閉包closure怎么使用

發布時間:2022-06-07 10:37:48 來源:億速云 閱讀:177 作者:iii 欄目:開發技術

這篇文章主要介紹“JavaScript中的閉包closure怎么使用”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“JavaScript中的閉包closure怎么使用”文章能幫助大家解決問題。

閉包簡述

Mozilla 上這樣解釋閉包:一個函數和對其周圍狀態(lexical environment,詞法環境) 的引用捆綁在一起(或者說函數被引用包圍),這樣的組合就是閉包(closure)。 也就是說,閉包讓你可以在一個內層函數中訪問到其外層函數的作用域。在 JavaScript 中, 每當創建一個函數, 閉包就會在函數創建的同時被創建出來。 詞法(lexical)一詞指的是,詞法作用域根據源代碼中聲明變量的位置來確定該變量在何處可用。

我對閉包的理解:閉包使得可以模擬私有項,可以使得內部函數可以訪問外部函數的屬性,非必要不用閉包。

1.閉包使得內部函數可以訪問外部函數的屬性(變量或方法)

這有時會帶來便利, 例如有時可以通過在外部函數聲明變量,代替全局變量。 下面是一個設備視口大小改變時,重置 echarts 的例子。

// 設備視口大小改變時,重置 echarts
let timer = null
window.onresize = function () {
  // 簡單的防抖動處理
  if (timer) clearTimeout(timer)
  timer = setTimeout(() => {
    console.log(timer)
    chart.resize()
  }, 500)
}

也可以考慮使用閉包的方式,而不必在聲明全局變量(更大范圍的變量) timer,例如這樣

window.onresize = this.debounce(() => {
  chart.resize()
}, 500)

function debounce (fn, delay = 500) {
  let timer = null
  return (p) => {
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
      fn(p)
    }, delay)
  }
}

2.閉包的廣闊應用場景

閉包的廣闊應用場景,體現在你使用只有一個方法的對象的地方,都可以使用閉包。

因為閉包允許將函數與其所操作的某些數據(環境)關聯起來。這顯然類似于面向對象編程。 在面向對象編程中,對象允許我們將某些數據(對象的屬性)與一個或者多個方法相關聯。

而在日常開發中,符合使用閉包的場景其實很常見,因為使用只有一個方法的對象的地方,都可以使用閉包, 而使用也并不太麻煩,加上閉包本身就是 javascript 的重要知識點,這些加起來使得閉包具備了實用的特征。

但如果你不熟練閉包,有更好的替代方案,也不必非要使用,因為實用好用的東西很多, 閉包只是選擇之一,為了給自己多一種選擇閉包又是要學的。

3.用閉包模擬私有方法

JavaScript 沒有類似 JAVA 那樣的將方法聲明為私有的原生支持,但我們可以使用閉包來模擬私有方法。 私有方法不僅僅有利于限制對代碼的訪問,還提供了管理全局命名空間的強大能力, 避免非核心的方法弄亂代碼的公共接口部分。

下面的示例展現了如何使用閉包來定義公共函數,并令其可以訪問私有函數和變量。這個方式也稱為模塊模式(module pattern)

window.onload = () => {
  let Counter1 = makeCounter(); // 創建實例1
  let Counter2 = makeCounter(); // 創建實例2

  console.log(Counter1.value()); // value:0
  Counter1.add(); // 調用增加函數,執行加一
  console.log(Counter1.value()); // value:1

  console.log(Counter2.value()); // value:0

  // 注意,實例2的 value 沒有受到實例1的影響,也就是說 Counter1 和 Counter2 各自獨立。
  // 每次調用其中一個計數器時,通過改變這個變量的值,會改變這個閉包的詞法環境。
  // 然而在一個閉包內對變量的修改,不會影響到另外一個閉包中的變量。

  // undefined,Counter1 無法直接訪問私有項 privateNumber
  console.log(Counter1.privateNumber);
  // Counter1.changeBy is not a function,Counter1 無法直接訪問私有項 changeBy
  console.log(Counter1.changeBy(10));

  // 問私有項無法被訪問,這提示我們應關注到以這種方式使用閉包,
  // 提供了許多與面向對象編程相關的好處 —— 特別是數據隱藏和封裝。
}

/// 聲明一個模塊:計數器,模塊內部包含了兩個模擬的私有項 privateNumber 和 changeBy,
// 并返回一個對象,對象內部包含三個屬性,分別是 add(),reduce(),value()。
let makeCounter = function () {
  let privateNumber = 0;

  function changeBy (val) {
    privateNumber += val;
  }

  return {
    add: function () {
      changeBy(1);
    },
    reduce: function () {
      changeBy(-1);
    },
    value: function () {
      return privateNumber;
    }
  }
};

在這個例子中,包含兩個私有項: 名為 privateCounter 的變量和名為 changeBy 的函數。 這兩項都無法在函數外部直接訪問。必須通過匿名函數返回的三個公共函數訪問。這就是模擬了私有特性。

4.從性能角度考慮,非必要不使用閉包

關于閉包的性能,我無深入的理解,也無數據證明,但我認為這挺重要的。

因此,這里引用一下 Mozilla 的說法:

如果不是某些特定任務需要使用閉包,在其它函數中創建函數是不明智的, 因為閉包在處理速度和內存消耗方面對腳本性能具有負面影響。

例如,在創建新的對象或者類時,方法通常應該關聯于對象的原型,而不是定義到對象的構造器中。 原因是這將導致每次構造器被調用時,方法都會被重新賦值一次(也就是說,對于每個對象的創建,方法都會被重新賦值)。

關于“JavaScript中的閉包closure怎么使用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

邵武市| 广东省| 宣城市| 遂平县| 富裕县| 宝鸡市| 密山市| 时尚| 清远市| 汪清县| 南丹县| 黔东| 屏南县| 星子县| 台前县| 濮阳市| 资源县| 彭山县| 潮安县| 乡城县| 徐闻县| 宁明县| 濮阳县| 江阴市| 都兰县| 阳朔县| 二连浩特市| 鹿邑县| 永宁县| 阳谷县| 珲春市| 大连市| 西和县| 阳信县| 会东县| 宣城市| 绵竹市| 吉林省| 钟祥市| 江孜县| 静宁县|