您好,登錄后才能下訂單哦!
這篇文章主要介紹“JavaScript中的閉包closure怎么使用”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“JavaScript中的閉包closure怎么使用”文章能幫助大家解決問題。
Mozilla 上這樣解釋閉包:一個函數和對其周圍狀態(lexical environment,詞法環境) 的引用捆綁在一起(或者說函數被引用包圍),這樣的組合就是閉包(closure)。 也就是說,閉包讓你可以在一個內層函數中訪問到其外層函數的作用域。在 JavaScript 中, 每當創建一個函數, 閉包就會在函數創建的同時被創建出來。 詞法(lexical)一詞指的是,詞法作用域根據源代碼中聲明變量的位置來確定該變量在何處可用。
我對閉包的理解:閉包使得可以模擬私有項,可以使得內部函數可以訪問外部函數的屬性,非必要不用閉包。
這有時會帶來便利, 例如有時可以通過在外部函數聲明變量,代替全局變量。 下面是一個設備視口大小改變時,重置 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) } }
閉包的廣闊應用場景,體現在你使用只有一個方法的對象的地方,都可以使用閉包。
因為閉包允許將函數與其所操作的某些數據(環境)關聯起來。這顯然類似于面向對象編程。 在面向對象編程中,對象允許我們將某些數據(對象的屬性)與一個或者多個方法相關聯。
而在日常開發中,符合使用閉包的場景其實很常見,因為使用只有一個方法的對象的地方,都可以使用閉包, 而使用也并不太麻煩,加上閉包本身就是 javascript 的重要知識點,這些加起來使得閉包具備了實用的特征。
但如果你不熟練閉包,有更好的替代方案,也不必非要使用,因為實用好用的東西很多, 閉包只是選擇之一,為了給自己多一種選擇閉包又是要學的。
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 的函數。 這兩項都無法在函數外部直接訪問。必須通過匿名函數返回的三個公共函數訪問。這就是模擬了私有特性。
關于閉包的性能,我無深入的理解,也無數據證明,但我認為這挺重要的。
因此,這里引用一下 Mozilla 的說法:
如果不是某些特定任務需要使用閉包,在其它函數中創建函數是不明智的, 因為閉包在處理速度和內存消耗方面對腳本性能具有負面影響。
例如,在創建新的對象或者類時,方法通常應該關聯于對象的原型,而不是定義到對象的構造器中。 原因是這將導致每次構造器被調用時,方法都會被重新賦值一次(也就是說,對于每個對象的創建,方法都會被重新賦值)。
關于“JavaScript中的閉包closure怎么使用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。