欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時(shí)間:2020年05月09日 09:50:40   作者:杜尼卜  
這篇文章主要介紹了JavaScript閉包原理與用法,結(jié)合實(shí)例形式詳細(xì)分析了JavaScript閉包相關(guān)概念、原理、用法及操作注意事項(xiàng),需要的朋友可以參考下

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

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

1.什么是閉包

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

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

概括:閉包就是一個(gè)具有封閉與包裹功能的結(jié)構(gòu)。函數(shù)可以構(gòu)成閉包。函數(shù)內(nèi)部定義的數(shù)據(jù)函數(shù)外部無法訪問,即函數(shù)具有封閉性;函數(shù)可以封裝代碼即具有包裹性,所以函數(shù)可以構(gòu)成閉包。

2.閉包有什么用(解決什么問題)?

  1. 閉包不允許外部訪問
  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ù)不能第二次訪問,因此第二次訪問的時(shí)候又要調(diào)用一次foo,表示又有一個(gè)新的num = 123出來了。

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

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

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

3.閉包使用舉例

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

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

如何完成讀取一個(gè)數(shù)據(jù)和修改這個(gè)數(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ù)使用權(quán),那么我們就可以總結(jié)出一個(gè)基本的使用模型。

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

5.閉包的基本用法

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

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

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

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

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

function createPerson() {
 var __name__ = "";
 return {
  getName: function () {
   return __name__;
  },
  setName: function( value ) {
   // 如果不姓張就報(bào)錯(cuò)
   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.沙箱模式(閉包應(yīng)用的一個(gè)典范)

7.1 沙箱的概念

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

7.2 沙箱模式

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

例如,在jQuery中

(function () {
 var jQuery = function () { // 所有的算法 }
 // .... // .... jQuery.each = function () {}
 window.jQuery = window.$ = jQuery;
})();
$.each( ... )

8.帶有緩存功能的函數(shù)

以 Fibonacci 數(shù)列為例,改進(jìn)傳統(tǒng)計(jì)算斐波那契數(shù)列方法
我們來回顧一下傳統(tǒng)遞歸方式求斐波那契數(shù)列方法,我們定義一個(gè)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

當(dāng) n = 5 式,count = 15,當(dāng)時(shí)當(dāng) n = 20 的時(shí)候,count就達(dá)到驚人的21891次,性能太低了

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

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

改進(jìn)版:

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

改進(jìn)之后, n = 100的時(shí)候也才199次,大大提高了性能。

9.閉包的性能問題

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

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

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

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

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

希望本文所述對大家JavaScript程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • JavaScript檢測鼠標(biāo)移動(dòng)方向的方法

    JavaScript檢測鼠標(biāo)移動(dòng)方向的方法

    這篇文章主要介紹了JavaScript檢測鼠標(biāo)移動(dòng)方向的方法,涉及javascript鼠標(biāo)操作的相關(guān)技巧,需要的朋友可以參考下
    2015-05-05
  • JavaScript 動(dòng)態(tài)加載腳本和樣式的方法

    JavaScript 動(dòng)態(tài)加載腳本和樣式的方法

    這篇文章主要介紹了JavaScript 動(dòng)態(tài)加載腳本和樣式的方法,需要的朋友可以參考下
    2015-04-04
  • Postman模擬發(fā)送帶token的請求方法

    Postman模擬發(fā)送帶token的請求方法

    下面小編就為大家分享一篇Postman模擬發(fā)送帶token的請求方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-03-03
  • javascript實(shí)現(xiàn)通過表格繪制顏色填充矩形的方法

    javascript實(shí)現(xiàn)通過表格繪制顏色填充矩形的方法

    這篇文章主要介紹了javascript實(shí)現(xiàn)通過表格繪制顏色填充矩形的方法,涉及javascript操作表格與樣式的相關(guān)技巧,需要的朋友可以參考下
    2015-04-04
  • 對TypeScript庫進(jìn)行單元測試的方法

    對TypeScript庫進(jìn)行單元測試的方法

    這篇文章主要介紹了對TypeScript庫進(jìn)行單元測試的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • JavaScript限定圖片顯示大小的方法

    JavaScript限定圖片顯示大小的方法

    這篇文章主要介紹了JavaScript限定圖片顯示大小的方法,涉及javascript針對圖片的操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-03-03
  • JavaScript設(shè)計(jì)模式之建造者模式實(shí)例教程

    JavaScript設(shè)計(jì)模式之建造者模式實(shí)例教程

    這篇文章主要介紹了JavaScript設(shè)計(jì)模式之建造者模式,結(jié)合實(shí)例形式分析了設(shè)計(jì)模式中建造者模式的概念、功能及JavaScript實(shí)現(xiàn)與使用建造者模式的相關(guān)操作技巧,需要的朋友可以參考下
    2018-07-07
  • JavaScript實(shí)現(xiàn)指定數(shù)量的并發(fā)限制的示例代碼

    JavaScript實(shí)現(xiàn)指定數(shù)量的并發(fā)限制的示例代碼

    這篇文章主要介紹了JavaScript實(shí)現(xiàn)指定數(shù)量的并發(fā)限制的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • bootstrap table實(shí)例詳解

    bootstrap table實(shí)例詳解

    本文通過實(shí)例代碼給大家介紹了bootstrap table樣式,非常不錯(cuò),具有參考借鑒價(jià)值,需要的的朋友參考下
    2017-01-01
  • React中過渡動(dòng)畫的編寫方式實(shí)例詳解

    React中過渡動(dòng)畫的編寫方式實(shí)例詳解

    在開發(fā)中我們想要給一個(gè)組件的顯示和消失添加某種過渡動(dòng)畫,可以很好的增加用戶體驗(yàn),下面這篇文章主要給大家介紹了關(guān)于React中過渡動(dòng)畫的編寫方式,需要的朋友可以參考下
    2022-10-10

最新評論