91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何使用JavaScript中的閉包

發布時間:2020-07-28 13:34:48 來源:億速云 閱讀:134 作者:小豬 欄目:web開發

這篇文章主要講解了如何使用JavaScript中的閉包,內容清晰明了,對此有興趣的小伙伴可以學習一下,相信大家閱讀完之后會有幫助。

1.什么是閉包

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

在JS中函數構成閉包。一般函數是一個代碼結構的封閉結構,即包裹的特性,同時根據作用域規則只允許函數訪問外部的數據,外部無法訪問函數內部的數據,即封閉的對外不公開的特性,因此說函數可以構成閉包。

概括:閉包就是一個具有封閉與包裹功能的結構。函數可以構成閉包。函數內部定義的數據函數外部無法訪問,即函數具有封閉性;函數可以封裝代碼即具有包裹性,所以函數可以構成閉包。

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

  1. 閉包不允許外部訪問
  2. 要解決的問題就是間接訪問該數據

函數就可以構成閉包,要解決的問題就是如何訪問到函數內部的數據

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

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

在函數內的數據,不能直接在函數外部訪問,那么在函數內如果定義一個函數,那么在這個函數內部中是可以直接訪問的

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

我們使用前面學習的繪制作用域鏈結構圖的方法來繪制閉包的作用域鏈結構圖,如下:

如何使用JavaScript中的閉包

3.閉包使用舉例

如何獲得超過一個數據

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

如何完成讀取一個數據和修改這個數據

function foo () {
 var num = Math.random();
 return {
  get_num : function () {
   return num;
  },
  set_num: function( value ) {
   return num = value;
  }
 }
}

4.基本的閉包結構

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

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

5.閉包的基本用法

閉包是為了實現具有私有訪問空間的函數的

帶有私有訪問數據的對象

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

所有的私有數據,就是說只有函數內部可以訪問的數據,或對象內部的方法可以訪問的數據

最簡單的實現:

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() );

帶有私有數據的函數

var func = function () {}
function func () {}
var foo = (function () {
 // 私有數據
 return function () {
  // 可以使用私有的數據
  ...
 };
});

6.閉包基本模型

對象模型

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

函數模型

function foo(){
 // 私有數據
 return function(){
   // 可以操作私有數據
 }
}

7.沙箱模式(閉包應用的一個典范)

7.1 沙箱的概念

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

7.2 沙箱模式

沙箱模式就是一個自調用函數,代碼寫到函數中一樣會執行,但是不會與外界有任何的影響

例如,在jQuery中

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

8.帶有緩存功能的函數

以 Fibonacci 數列為例,改進傳統計算斐波那契數列方法
我們來回顧一下傳統遞歸方式求斐波那契數列方法,我們定義一個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次,性能太低了

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

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

改進版:

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.閉包的性能問題

函數執行需要內存,那么函數中定義的變量,會在函數執行結束后自動回收,凡是因為閉包結構的,被引出的數據,如果還有變量引用這些數據的話,那么這些數據就不會被回收。

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

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

看完上述內容,是不是對如何使用JavaScript中的閉包有進一步的了解,如果還想學習更多內容,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

秦安县| 铜梁县| 常州市| 察哈| 石柱| 金阳县| 新余市| 大港区| 蒲城县| 崇州市| 青阳县| 措美县| 张家港市| 丘北县| 福清市| 无棣县| 图片| 颍上县| 荔浦县| 巧家县| 天长市| 安岳县| 临洮县| 教育| 绿春县| 民勤县| 博乐市| 自贡市| 南岸区| 巢湖市| 阿荣旗| 水富县| 祁东县| 兰溪市| 宝鸡市| 双鸭山市| 广西| 云梦县| 仲巴县| 通州市| 开江县|