javascript學習筆記---ECMAScript 函數 --閉包(closure)

ECMAScript 最易讓人誤解的一點是,它支持閉包(closure)。閉包

閉包,指的是詞法表示包括不被計算的變量的函數,也就是說,函數可使用函數以外定義的變量。函數

簡單的閉包實例

在 ECMAScript 中使用全局變量是一個簡單的閉包實例。請思考下面這段代碼:spa

var sMessage = "hello world";

function sayHelloWorld() {
  alert(sMessage);
}

sayHelloWorld();

在上面這段代碼中,腳本被載入內存後,並無爲函數 sayHelloWorld() 計算變量 sMessage 的值。該函數捕獲 sMessage 的值只是爲了之後的使用,也就是說,解釋程序知道在調用該函數時要檢查 sMessage 的值。sMessage 將在函數調用 sayHelloWorld() 時(最後一行)被賦值,顯示消息 "hello world"。ip

複雜的閉包實例

在一個函數中定義另外一個會使閉包變得更加複雜。例如:內存

var iBaseNum = 10;

function addNum(iNum1, iNum2) {
  function doAdd() {
    return iNum1 + iNum2 + iBaseNum;
  }
  return doAdd();
}

這裏,函數 addNum() 包括函數 doAdd() (閉包)。內部函數是一個閉包,由於它將獲取外部函數的參數 iNum1 和 iNum2 以及全局變量 iBaseNum 的值。 addNum() 的最後一步調用了 doAdd(),把兩個參數和全局變量相加,並返回它們的和。get

這裏要掌握的重要概念是,doAdd() 函數根本不接受參數,它使用的值是從執行環境中獲取的。io

能夠看到,閉包是 ECMAScript 中很是強大多用的一部分,可用於執行復雜的計算。function

提示:就像使用任何高級函數同樣,使用閉包要當心,由於它們可能會變得很是複雜。class

 在來兩個例子:變量

function foo(x) {
var tmp = 3;
return function (y) {
    alert(x 
+ y + tmp);
    x.memb 
= x.memb ? x.memb 1 : 1;
    alert(x.memb);
    }
}
var age = new Number(2);
var bar = foo(age); // bar 如今是一個引用了age的閉包
bar(
10);

 不出咱們意料,每次運行bar(10),x.memb都會自加1。但須要注意的是x每次都指向同一個object變量——age,運行兩次bar(10)後,age.memb會變成2.

 

var db = (function() {
// 建立一個隱藏的object, 這個object持有一些數據
// 從外部是不能訪問這個object的
var data = {};
// 建立一個函數, 這個函數提供一些訪問data的數據的方法
return function(key, val) {
    if (val === undefined) { return data[key] } // get
    else { return data[key] = val } // set
    }
// 咱們能夠調用這個匿名方法
// 返回這個內部函數,它是一個閉包
})();

db(
'x'); // 返回 undefined
db(
'x'1); // 設置data['x']爲1
db(
'x'); // 返回 1
// 咱們不可能訪問data這個object自己
// 可是咱們能夠設置它的成員

閉包常常用於建立含有隱藏數據的函數(但並不老是這樣)。

相關文章
相關標籤/搜索