摘要:要使用閉包,需要在另一個函數中創建一個函數,這種函數被稱為嵌套函數。只有名為閉包的功能才能對此進行訪問。結論閉包是外部函數中的變量集合,它提供對內部函數作用域的訪問以保護全局命名空間。
翻譯:瘋狂的技術宅
https://medium.freecodecamp.o...
本文首發微信公眾號:前端先鋒
歡迎關注,每天都給你推送新鮮的前端技術文章
閉包是函數創建時作用域內所有變量的集合。要使用閉包,需要在另一個函數中創建一個函數,這種函數被稱為嵌套函數。內部函數可以訪問外部函數作用域中的變量(依靠閉包可以訪問外部函數作用域),即使在返回外部函數之后也是如此。每次創建嵌套函數時都會創建閉包。
在繼續了解閉包之前,首先了解一下JavaScript中的作用域鏈。
通常,有兩種類型的作用域:
全局作用域
局部作用域
在JavaScript中,函數內部的變量在外部是不可見的。但是在塊內的變量(if 或 while 之類)是可見的。
因此,JavaScript有函數作用域。沒有塊作用域。
var a = 10; function app(){ var b = 2; console.log(a); // 10 console.log(b); // 2 } console.log(b); // ReferenceError: b is not defined app();
正像我們已知的那樣,a 是一個全局變量并且 b 是一個局部變量,它是app函數獨有的。
我們無法從局部作用域之外獲取局部變量的值。
使用嵌套函數 —— 函數內部的函數var a = 10; function app(){ var b = 2; var d = 3; function add(){ var c = a + b; } return add; } var x = app(); console.dir(x);
在這里app是父函數,add函數是子函數。
代碼中沒有用 console.log 而是用了console.dir 來輸出指定JavaScript對象的所有屬性,這有助于開發人員獲取對象的屬性
變量 x 被分配給app函數,app函數返回add函數。因此我們可以看到add函數的所有對象屬性。
如果在瀏覽器中查看控制臺,可以在Scopes數組中看到Closure對象。
由于內部函數add訪問外部函數變量b 和 d,因此這2個變量將被添加到Closure對象中以供引用。
讓我們看看下一個例子:
var a = 10; var startFunc; function app(){ var b = 2; function add(){ var c = a + b; console.log(c); } startFunc = add(); } app(); // 調用app函數 startFunc; // 上面調用的app函數會將add函數賦值給startFunc并輸出c的值
一個名為 startFunc 的全局函數被分配給add函數,該函數是 app 函數的子函數。
這只有在調用 app 函數后才有可能,否則 startFunc 將作為全局變量而不被分配任何值
在JavaScript中使用閉包很多人在編碼時會用到閉包,但是不明白用它的原因。 JavaScript沒有像其他面向對象語言一樣的訪問修飾符,例如 private,public,protected。不過我們可以利用函數來保護命名空間免受外部代碼使用的影響。
特別是在函數中,立即執行函數表達式(IIFE)是在聲明之后會立即執行的函數表達式。在聲明函數之后,你不需要去調用該函數。
IIFE的語法定義是:
(function(){ //函數內部的變量和作用域 })();
舉個例子:
var studnetEnrollment = (function () { //私有變量,任何人都無法改變 //除了下面聲明的函數 var count = 0; var prefix = "S"; // 返回一個命名函數表達式 function innerFunc() { count = count + 1; return prefix + count; }; return innerFunc; })(); var x = studnetEnrollment(); // S1 console.log(x); var y = studnetEnrollment(); // S2 console.log(y);
count和prefix是兩個私有變量,任何人都無法進行更改,只能訪問內部函數(即代碼中的innerFunc)。只有名為閉包的功能才能對此進行訪問。
第一次調用studentEnrollment函數時,函數內的count變量由innerFunc函數遞增加1。
第二次,增加上一個計數值,即 1 增加到 2
Closure功能可以實現這些功能。
結論閉包是外部函數中的變量集合,它提供對內部函數作用域的訪問以保護全局命名空間。
閉包使開發人員能夠編寫像面向對象語言那樣的干凈代碼,這些代碼不會混淆全局和局部變量的名稱。
編碼快樂...... !!!!!
本文首發微信公眾號:前端先鋒 歡迎掃描二維碼關注公眾號,每天都給你推送新鮮的前端技術文章 歡迎繼續閱讀本專欄其它高贊文章:12個令人驚嘆的CSS實驗項目
必須要會的 50 個React 面試題
世界頂級公司的前端面試都問些什么
11 個最好的 JavaScript 動態效果庫
CSS Flexbox 可視化手冊
從設計者的角度看 React
過節很無聊?還是用 JavaScript 寫一個腦力小游戲吧!
CSS粘性定位是怎樣工作的
一步步教你用HTML5 SVG實現動畫效果
程序員30歲前月薪達不到30K,該何去何從
14個最好的 JavaScript 數據可視化庫
8 個給前端的頂級 VS Code 擴展插件
Node.js 多線程完全指南
把HTML轉成PDF的4個方案及實現
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/104124.html
摘要:閉包引起的內存泄漏總結從理論的角度將由于作用域鏈的特性中所有函數都是閉包但是從應用的角度來說只有當函數以返回值返回或者當函數以參數形式使用或者當函數中自由變量在函數外被引用時才能成為明確意義上的閉包。 文章同步到github js的閉包概念幾乎是任何面試官都會問的問題,最近把閉包這塊的概念梳理了一下,記錄成以下文章。 什么是閉包 我先列出一些官方及經典書籍等書中給出的概念,這些概念雖然...
摘要:深入系列第八篇,介紹理論上的閉包和實踐上的閉包,以及從作用域鏈的角度解析經典的閉包題。定義對閉包的定義為閉包是指那些能夠訪問自由變量的函數。 JavaScript深入系列第八篇,介紹理論上的閉包和實踐上的閉包,以及從作用域鏈的角度解析經典的閉包題。 定義 MDN 對閉包的定義為: 閉包是指那些能夠訪問自由變量的函數。 那什么是自由變量呢? 自由變量是指在函數中使用的,但既不是函數參數也...
摘要:實用價值在于可以防止全局污染。別忘了有判定的當然,很明顯,這只是基礎,并不能更裝逼一點。祝愿大家越玩越牛逼從一行代碼里面學點深入淺出高級程序設計設計模式與開發實踐原文裝逼指南順便求實習 Summary 本文秉承著 你看不懂是你sb,我寫的代碼就是牛逼 的理念來介紹一些js的裝逼技巧。 下面的技巧,后三個,請謹慎用于團隊項目中(主要考慮到可讀性的原因),不然,leader 可能請你喝茶。...
摘要:理解的函數基礎要搞好深入淺出原型使用原型模型,雖然這經常被當作缺點提及,但是只要善于運用,其實基于原型的繼承模型比傳統的類繼承還要強大。中文指南基本操作指南二繼續熟悉的幾對方法,包括,,。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。 怎樣使用 this 因為本人屬于偽前端,因此文中只看懂了 8 成左右,希望能夠給大家帶來幫助....(據說是阿里的前端妹子寫的) this 的值到底...
閱讀 1588·2019-08-30 13:18
閱讀 1577·2019-08-29 12:19
閱讀 2094·2019-08-26 13:57
閱讀 4137·2019-08-26 13:22
閱讀 1179·2019-08-26 10:35
閱讀 2991·2019-08-23 18:09
閱讀 2500·2019-08-23 17:19
閱讀 676·2019-08-23 17:18