成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Javascript中的暗物質:閉包

開發 前端
如何在javascript實現數據的保護呢?閉包就是實現它的利器,這需要我們放下普通的對象,理解一下javascript的工作原理。

1. 詭異的閉包

javascript 中有一個特殊的特性 - 閉包,對于 .NET 程序員來說,比較熟悉的是面向對象的程序設計 OOP,  而來自函數式語言的閉包則顯得比較詭異,許多程序員對它敬而遠之。

對于閉包我們還是要從函數式語言的特點說起。

不知道你有沒有發現,在 javascript 中沒有 public ,private 之類的關鍵字,也沒有 class ,雖然也存在對象一說,但是對象的地位遠遠沒有在 C# 中是一等公民,在 js 中,沒有對象你也可以一樣寫程序。它只是一種數據的表示形式而已,可有也可無。

2. 閉包何來?

如何在 javascript 實現數據的保護呢?閉包就是實現它的利器,這需要我們放下普通的對象,理解一下 javascript 的工作原理。

在 javascript 中,可以在函數中定義新的函數,這種嵌套函數還可以作為函數的返回值,被外部的變量所引用。在普通的程序設計語言中,比如 C 中,雖然也存在函數指針的概念,但是,所謂的函數指針僅僅是一段代碼的地址而已,而 javascript 中返回的函數引用,則不限于此。

在 C 語言中,在函數運行的時候,局部變量是保存在堆棧中的,函數執行完畢,系統所做的是彈出堆棧。

實際上,在 javascript 中,函數每次執行的時候,注意是運行時,系統會同時創建一個此次函數運行的環境對象,而此次運行期間的局部變量則關聯在這個環境對象上,在普通不返回函數 的普通函數中,函數執行完畢,則環境對象也一起釋放。而如果函數返回了定義在外部函數中的嵌套函數,那么,這個環境對象將不會釋放,也就是說,這個時候, 返回了一個看得見的函數對象,還附帶了一個看不見的暗物質 - 外部函數的環境對象。

看得見的函數對象加上隱含的環境對象就是閉包。

這個環境對象只能通過這個函數隱式訪問,我們并沒有它的引用,也無法直接訪問它。結果就是實現了信息的隱藏。

3. 實現私有的數據

考慮下面的代碼

  1. function outer() { 
  2.     var name = "Alice"
  3.     var inner = function () { 
  4.         return name; 
  5.     } 
  6.     return inner; 
  7.  
  8. var fn = outer(); 
  9. alert(fn()); 

 在這個例子中,看起來簡單的 fn 函數背后,其實暗藏了在執行 outer 函數時期創建的環境對象,所以通過 fn 可以得到 Alice 這個名字,而且沒有其他的渠道允許得到這個名字。

4. 為什么數據搞亂了?

再看另外一個經典的例子。

  1. <body> 
  2.     <div> 
  3.         <a href="#">Click Me!</a> 
  4.         <a href="#">Click Me!</a> 
  5.         <a href="#">Click Me!</a> 
  6.     </div> 
  7.     <script type ="text/javascript"
  8.         function main(links) { 
  9.             for (var i = 0; i < links.length; i++) { 
  10.                 links[i].onclick = function () { 
  11.                     alert(i + 1); 
  12.                 } 
  13.             } 
  14.         }; 
  15.         main(document.getElementsByTagName("a")); 
  16.     </script> 
  17.  
  18. </body> 

彈出的是多少呢?感覺有三次循環,應該彈出 1, 2, 3。運行一下,你會看到實際上是 4, 4, 4!

是不是非常詭異?

從閉包的角度來說,則非常簡單,main 函數執行了幾次呢?只有一次,在執行的時候創建了一個閉包對象,其中引用了定義在 main 中的局部變量 i,在循環體中,實際上創建了三個內部函數,它們引用的都是同一個環境對象。這些函數注冊到鏈接的 onclick 事件上,其實也就是已經傳出了函數 main,所以,main 的環境對象也就悄悄地成為了暗物質,而循環完成之后 i 已經最終被賦予了 3 這個值,三個函數訪問的是同一個環境對象中的 i, 所以,在點擊鏈接的時候看到 4 這個結果也就正常了。

5. 解鈴還需系鈴人

如果希望得到的是 1, 2, 3 這個結果又該怎么辦呢?

我們可以定義一個內部函數,讓它執行三次,這個將會創建三個對應的環境對象,我們可以使得這三個環境對象包含不同的值。

  1. function main(links) { 
  2.     var inner = function (elem, i) { 
  3.         elem.onclick = function () { 
  4.             alert(i + 1); 
  5.         }; 
  6.     }; 
  7.     for (var i = 0; i < links.length; i++) { 
  8.         var elem = links[i]; 
  9.         inner(elem, i); 
  10.     } 
  11. }; 

由于 inner 函數執行了三次,所以將會創建三個不同的環境對象,每個環境對象中的 i 都是不同的值。這樣注冊到 onclick 中的函數就可以訪問到不同的值了。

閉包的概念

這里,我們可以看一下閉包的概念了。來自 Wiki 的說明是這樣的

在計算機科學中,閉包(Closure)是詞法閉包(Lexical Closure)的簡稱,是引用了自由變量的函數。這個被引用的自由變量將和這個函數一同存在,即使已經離開了創造它的環境也不例外。所以,有另一種說法認為閉包是由函數和與其相關的引用環境組合而成的實體。

原文鏈接:http://www.cnblogs.com/haogj/archive/2012/11/28/2793535.html

責任編輯:林師授 來源: 博客園
相關推薦

2012-04-26 09:45:52

程序員

2011-05-12 18:26:08

Javascript作用域

2021-02-21 16:21:19

JavaScript閉包前端

2016-09-14 09:20:05

JavaScript閉包Web

2009-07-24 17:30:37

Javascript閉

2020-10-14 15:15:28

JavaScript(

2011-05-25 14:48:33

Javascript閉包

2023-10-26 07:47:35

JavaScript代碼變量

2020-02-12 16:58:15

JavaScript前端技術

2010-06-23 10:24:42

Javascript閉

2016-09-18 20:53:16

JavaScript閉包前端

2017-09-14 13:55:57

JavaScript

2023-09-06 16:55:33

JavaScript閉包

2011-03-02 12:33:00

JavaScript

2020-09-29 06:39:38

智能

2021-12-06 07:15:48

Javascript作用域閉包

2017-05-22 16:08:30

前端開發javascript閉包

2021-01-13 11:25:12

JavaScript閉包函數

2009-03-17 15:36:29

JavaScript循環事件

2016-11-01 09:18:33

Python閉包
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: av在线一区二区三区 | 在线欧美日韩 | 成人精品一区二区 | 激情毛片 | 一区视频在线播放 | 香蕉一区二区 | 91精品国产乱码久久久 | 久久国产精品99久久久大便 | 亚洲精品在线免费看 | 凹凸日日摸日日碰夜夜 | 亚洲欧美日韩中文字幕一区二区三区 | 国产精品久久久久永久免费观看 | 亚洲国产精品一区二区久久 | 亚洲国产小视频 | 色播久久久 | 国产探花在线精品一区二区 | 日韩一区二区三区在线 | 一区二区日韩 | 精品自拍视频 | 一区二区三区中文字幕 | 97视频久久 | 成人超碰 | 激情91| 欧美一区二区三区视频在线观看 | 亚洲另类视频 | 午夜手机在线视频 | 在线视频亚洲 | 九九热这里只有精品在线观看 | 黄色一级免费 | 天天射网站| 日韩精品一区二区三区老鸭窝 | 激情欧美一区二区三区中文字幕 | 国产在线一区二区三区 | 欧美激情精品久久久久久 | 亚洲精品电影 | h视频免费在线观看 | 91精品国产综合久久久久久丝袜 | 欧美亚洲国产日韩 | 日韩中文电影 | 精品国产一区二区三区性色av | 国产精品久久久久久中文字 |