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

首頁 > 編程 > JavaScript > 正文

JavaScript 閉包詳細介紹

2019-11-20 08:51:18
字體:
來源:轉載
供稿:網友

深入理解JavaScript――閉包

  跟很多新手一樣我也是初入前端,對閉包的理解花費的時間和精力相當的多。效果也還行,今天我就來根據自己的理解細致的講一講閉包,由于是初入學習的時候不免有一些彎路和困惑,我想信這也是很多跟我一樣的人會同樣遇到的問題。我就以自己的學習路徑和遇到的各種坑來談閉包。希望對各位有一定的幫助。(菜鳥,也請各位多多指教)

  閉包是什么?《JavaScript高級程序設計》上面這么描述的:閉包是指有權訪問另一個函數作用域中的變量的函數。這句話第一次看的時候模模糊糊,似是而非。碰到問題就不會運用了,聽別人的分析頭頭是道,說到底還是沒搞明白。現在我覺得要徹底搞清這句話必須對JavaScript的作用域,匿名函數,甚至JavaScript的編譯原理有一些簡單的了解。經過查閱理解各種資料書籍對閉包的解釋,再回過頭來看了一些源碼,慢慢的有了一點感覺。我覺得對閉包描述最好的一句話是:“閉包是基于詞法作用域書寫代碼時所產生的自然結果,你甚至不需要為了利用它而有意為之的創建閉包,閉包的創建和使用是在你的代碼中隨處可見。你缺少的是根據你自己的意愿來識別,擁抱和影響閉包的思維環境。”話有點長但點出來閉包在JavaScript這么語言中存在的實際價值,大家可以細細體會一下。接下來我已實際例子來講講閉包。

首先看一個簡單的例子:

function createComparisonFunction(propertyName){  return function(obj1,obj2){    var value1=object1[propertyName];    var value2=object2[propertyName];    if(value1<value2){      return -1;    }else if(value1>value2){      return 1;    }else{      return 0;    }  } }

例子中返回的是一個匿名函數,其中匿名函數中value1,value2同時又對外部函數createComparisonFunction()的參數propertyName進行調用。再看看上面對閉包的定義:有權訪問另一個函數作用域中的變量的函數。return的匿名函數有權訪問外部函數作用域中的變量propertyName,因此這是一個閉包。但實際來說這只是一個基于詞法作用域的查找規則,很好理解也很自然。

  可能有些人不明白什么是詞法作用域的查找規則:其實說簡單點就是根據變量的作用鏈域來查找并取得該變量。以上例來說:createComparisonFunction函數的作用域包含一個變量property和一個匿名函數(由于沒有函數名其實在createComparisonFunction函數中也無法調用,這也是匿名函數的一個缺點,記得事件監聽函數調用一個匿名函數時是無法移除嗎?道理是一樣的),匿名函數作用域中包括obj1,obj2,value1,value2這四個變量。匿名函數中的變量調用時首先在自己作用域中查詢,找到了該變量就調用,找不到就往外層走接著找,直到全局作用域如果還是找不到就會報ReferenceError(如果找到了一個var a;呢?由于a為undefined所以會報TypeError)。而createComparisonFunction函數則只能在他的作用域中查找,不能去內層的匿名函數中查找,這種查找規則就是詞法作用域的查找規則(當然這不只是基本規則)。

 我們再來看一個例子:

function foo() {  var a = 2;  function bar() {    console.log( a );  }  return bar;}var baz = foo();baz();  //2

  答案可能很多人都能猜出來但其實現原理是怎樣呢?我現在就來細致的分析一下:首先聲明了一個函數foo其作用域包括變量a和bar函數。foo函數內部有一個函數bar內部沒有新變量。然后定義一個變量baz,其值為foo()而foo()返回bar,顧baz=bar;最后一句baz()即等價于bar();根據詞法作用域的規則bar是在foo函數中聲明的。外部是無法訪問的呀!這正是閉包的神奇之處!我們再一次回到閉包定義:有權訪問另一個函數作用域中的變量的函數,baz()函數有權訪問foo函數中的bar。這就是閉包對吧!搞清閉包后有些人還會疑問?閉包是怎么形成的,為什么你說它有權訪問foo中的bar呢?首先閉包的形成是在一個函數內部創建一個函數這是創建閉包的最常見方法。當將內部函數傳遞到它的詞法作用域以外他都會持有對原始定義作用域的引用,執行此函數就會 使用閉包。

  閉包的基礎大概就是這幾點,希望大家能仔細體會。抽時間補充點閉包的一些其他用途,來幫大家擴展一下思維。

        通過此文,希望大家對閉包的知識掌握,謝謝大家對本站的支持!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 获嘉县| 荆州市| 濉溪县| 翼城县| 长垣县| 同德县| 邹城市| 石渠县| 社旗县| 红桥区| 常山县| 方山县| 黑水县| 浦县| 平潭县| 馆陶县| 江城| 马山县| 江西省| 玉树县| 鄂尔多斯市| 连南| 双峰县| 衡水市| 巩义市| 河源市| 金塔县| 桐庐县| 泰和县| 双鸭山市| 冕宁县| 石阡县| 九寨沟县| 玉山县| 依兰县| 葵青区| 乐清市| 公主岭市| 公主岭市| 西乌珠穆沁旗| 正定县|