亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁技術文章
文章詳情頁

JavaScript進階(三)閉包原理與用法詳解

瀏覽:77日期:2023-10-29 10:43:29

本文實例講述了JavaScript閉包原理與用法。分享給大家供大家參考,具體如下:

為了更好的理解,在閱讀此文之前建議先閱讀上一篇《JavaScript詞法作用域與作用域鏈》 1.什么是閉包

閉包的含義就是閉合,包起來,簡單的來說,就是一個具有封閉功能與包裹功能的結(jié)構(gòu)。所謂的閉包就是一個具有封閉的對外不公開的,包裹結(jié)構(gòu),或空間。

在JS中函數(shù)構(gòu)成閉包。一般函數(shù)是一個代碼結(jié)構(gòu)的封閉結(jié)構(gòu),即包裹的特性,同時根據(jù)作用域規(guī)則只允許函數(shù)訪問外部的數(shù)據(jù),外部無法訪問函數(shù)內(nèi)部的數(shù)據(jù),即封閉的對外不公開的特性,因此說函數(shù)可以構(gòu)成閉包。

概括:閉包就是一個具有封閉與包裹功能的結(jié)構(gòu)。函數(shù)可以構(gòu)成閉包。函數(shù)內(nèi)部定義的數(shù)據(jù)函數(shù)外部無法訪問,即函數(shù)具有封閉性;函數(shù)可以封裝代碼即具有包裹性,所以函數(shù)可以構(gòu)成閉包。2.閉包有什么用(解決什么問題)? 閉包不允許外部訪問 要解決的問題就是間接訪問該數(shù)據(jù)

函數(shù)就可以構(gòu)成閉包,要解決的問題就是如何訪問到函數(shù)內(nèi)部的數(shù)據(jù)

function foo () { var num = 123; return num;}var res = foo();console.log( res ); // =>123

這里的確是訪問到函數(shù)中的數(shù)據(jù)了。但是該數(shù)據(jù)不能第二次訪問,因此第二次訪問的時候又要調(diào)用一次foo,表示又有一個新的num = 123出來了。

在函數(shù)內(nèi)的數(shù)據(jù),不能直接在函數(shù)外部訪問,那么在函數(shù)內(nèi)如果定義一個函數(shù),那么在這個函數(shù)內(nèi)部中是可以直接訪問的

function foo() { var num = Math.random(); function func() { return mun; } return func;}var f = foo();// f 可以直接訪問這個 numvar res1 = f();var res2 = f();

我們使用前面學習的繪制作用域鏈結(jié)構(gòu)圖的方法來繪制閉包的作用域鏈結(jié)構(gòu)圖,如下:

JavaScript進階(三)閉包原理與用法詳解

3.閉包使用舉例

如何獲得超過一個數(shù)據(jù)

function foo () { var num1 = Math.random(); var num2 = Math.random(); return { num1: function () { return num1; }, num2: function () { return num2; } }}

如何完成讀取一個數(shù)據(jù)和修改這個數(shù)據(jù)

function foo () { var num = Math.random(); return { get_num : function () { return num; }, set_num: function( value ) { return num = value; } }}4.基本的閉包結(jié)構(gòu)

一般閉包的問題就是要想辦法簡潔的獲取函數(shù)內(nèi)的數(shù)據(jù)使用權,那么我們就可以總結(jié)出一個基本的使用模型。

寫一個函數(shù),函數(shù)內(nèi)部定義一個新函數(shù),返回新函數(shù),用新函數(shù)獲得函數(shù)內(nèi)的數(shù)據(jù) 寫一個函數(shù),函數(shù)內(nèi)部定義個一個對象,對象中綁定多個函數(shù)(方法),返回對象,利用對象的方法訪問函數(shù)內(nèi)的數(shù)據(jù)5.閉包的基本用法

閉包是為了實現(xiàn)具有私有訪問空間的函數(shù)的

帶有私有訪問數(shù)據(jù)的對象

function Person() { this.name = '張三'; // setName( ’’ )}

所有的私有數(shù)據(jù),就是說只有函數(shù)內(nèi)部可以訪問的數(shù)據(jù),或?qū)ο髢?nèi)部的方法可以訪問的數(shù)據(jù)

最簡單的實現(xiàn):

function createPerson() { var __name__ = ''; return { getName: function () { return __name__; }, setName: function( value ) { // 如果不姓張就報錯 if ( value.charAt(0) === ’張’ ) { __name__ = value; } else { throw new Error( ’姓氏不對,不能取名’ ); } } }}var p = createPerson();p.set_Name( ’張三豐’ );console.log( p.get_Name() );p.set_Name( ’張王富貴’ );console.log( p.get_Name() );

帶有私有數(shù)據(jù)的函數(shù)

var func = function () {}function func () {}var foo = (function () { // 私有數(shù)據(jù) return function () { // 可以使用私有的數(shù)據(jù) ... };});6.閉包基本模型

對象模型

function foo () { // 私有數(shù)據(jù) return { method : function(){ // 操作私有數(shù)據(jù) } }}

函數(shù)模型

function foo(){ // 私有數(shù)據(jù) return function(){ // 可以操作私有數(shù)據(jù) }}7.沙箱模式(閉包應用的一個典范)7.1 沙箱的概念

沙盤與盒子,就可以在一個笑笑的空間內(nèi)模擬顯示世界,特點是執(zhí)行效果與現(xiàn)實世界一模一樣,但是在沙箱中模擬與現(xiàn)實無關.

7.2 沙箱模式

沙箱模式就是一個自調(diào)用函數(shù),代碼寫到函數(shù)中一樣會執(zhí)行,但是不會與外界有任何的影響

例如,在jQuery中

(function () { var jQuery = function () { // 所有的算法 } // .... // .... jQuery.each = function () {} window.jQuery = window.$ = jQuery;})();$.each( ... )8.帶有緩存功能的函數(shù)

以 Fibonacci 數(shù)列為例,改進傳統(tǒng)計算斐波那契數(shù)列方法 我們來回顧一下傳統(tǒng)遞歸方式求斐波那契數(shù)列方法,我們定義一個count變量來查看遞歸了多少次:

var count = 0;function fibo( n ){ count++; if( n ==0 || n == 1 ) return 1; return fibo( n - 1 ) + fibo( n - 2 );}fib1( 20 );console.log( count1 );// 5: 15// 6: 25// ...// 20: 21891

當 n = 5 式,count = 15,當時當 n = 20 的時候,count就達到驚人的21891次,性能太低了

性能低的原因是 重復計算。如果每次將計算的結(jié)果存起來

那么每次需要的時候先看看有沒有存儲過該數(shù)據(jù),如果有,直接拿來用。 如果沒有再遞歸,但是計算的結(jié)果需要再次存儲起來,以便下次使用

改進版:

var data = [ 1, 1 ];var count = 0;function fibo( n ) { count++; var v = data[ n ]; if( v === undefined ){ v = fibo( n - 1 ) + fibo( n - 2 ); data[ n ] = v; } return v;}fibo( 100 );console.log( count ); // 199

改進之后, n = 100的時候也才199次,大大提高了性能。

9.閉包的性能問題

函數(shù)執(zhí)行需要內(nèi)存,那么函數(shù)中定義的變量,會在函數(shù)執(zhí)行結(jié)束后自動回收,凡是因為閉包結(jié)構(gòu)的,被引出的數(shù)據(jù),如果還有變量引用這些數(shù)據(jù)的話,那么這些數(shù)據(jù)就不會被回收。

因此在使用閉包的時候如果不適用某學數(shù)據(jù)了,一定要賦值一個null

var f = (function () { var num = 123; return function () { return num; };})();// f 引用著函數(shù),函數(shù)引用著變量num// 因此在不適用該數(shù)據(jù)的時候,最好寫上f = null;

感興趣的朋友可以使用在線HTML/CSS/JavaScript代碼運行工具:http://tools.jb51.net/code/HtmlJsRun測試上述代碼運行效果。

更多關于JavaScript相關內(nèi)容可查看本站專題:《JavaScript常用函數(shù)技巧匯總》、《javascript面向?qū)ο笕腴T教程》、《JavaScript錯誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》及《JavaScript數(shù)學運算用法總結(jié)》

希望本文所述對大家JavaScript程序設計有所幫助。

標簽: JavaScript
相關文章:
主站蜘蛛池模板: 国产成人a一在线观看 | 久久视频在线观看免费 | 国产女人成人精品视频 | 国内精品视频在线播放 | 黑人狂躁日本妞 | 久久综合久美利坚合众国 | 在线观看日本永久免费视频 | 黄色一级大片网站 | 国内精品久久久久鸭 | 国产成人精品综合在线观看 | 日本制服丝袜在线 | 高清国产亚洲va精品 | 欧美一二区 | 成人午夜小视频 | 做爰全过程免费的视69频 | 黄色免费看片网站 | 欧美色黄| 欧美日韩国产精品综合 | 欧美成人免费mv在线播放 | 国产精品不卡 | 最近免费中文字幕大全免费版视频 | 手机在线一区二区三区 | 国产精品国产亚洲精品看不卡 | 日本一级特黄在线播放 | 日本黄色网页 | 日韩精品一区二区三区 在线观看 | 日本一二三本免费视频 | 国产高清美女一级a毛片久久w | 成人性视屏 | 日韩国产欧美一区二区三区 | 女黄色片| 制服丝袜中文在线 | 97超视频在线观看 | 日韩免费一级片 | 亚洲毛片大全 | 成人网址大全 | 日韩一级不卡 | 欧美 日产 国产精品 | 青草草在线观看免费视频 | 国产精品视频在线播放 | 美女污污视频在线观看 |