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自己
// 可是咱们能够设置它的成员

闭包常常用于建立含有隐藏数据的函数(但并不老是这样)。

相关文章
相关标签/搜索