引入
匿名函数
闭包
变量作用域
函数外部访问函数内部的局部变量
用闭包实现私有成员
引入
闭包是用匿名函数来实现。闭包就是一个受到保护的变量空间,由内嵌函数生成。“保护变量”的思想在几乎所有的编程语言中都能看到。
先看下 JavaScript 作用域:
JavaScript 具有函数级的作用域。这意味着,不能在函数外部访问定义在函数内部的变量。
JavaScript 的作用域又是词法性质的(lexically scoped)。这意味着,函数运行在定义它的作用域中,而不是在调用它的作用域中。这是 JavaScript 的一大特色,将在后面说明。
把这两个因素结合在一起,就能通过把变量包裹在匿名函数中而对其加以保护。你可以这样创建类的私有变量:
var baz; (function() { var foo = 10; var bar = 2; baz = function() { return foo * bar; }; })(); baz();
尽管在匿名函数外执行,但 baz 仍然可以访问 foo 和 bar。
说明:
1,第 1 行,baz 是全局变量;
2,第 3 ~第 9 行,定义一个匿名函数;
3,第 4 和 5 行,foo 和 bar 是匿名函数内的局部变量;第 6 ~ 8 行,在匿名函数内定义一个匿名函数,并将其赋值给全局变量 baz;
4,第 10 行,调用 baz。若改成 "alert(baz());",将显示 20;
5,按理说,在匿名函数外不能访问 foo 和 bar,但是现在可以。
在说明闭包前,先了解一下匿名函数。
匿名函数
匿名函数是指那些无需定义函数名的函数。匿名函数与 Lambda 表达式(拉姆达表达式)是一回事。唯一的不同——语法形式不同。Lambda 表达式更进一步。本质上,它们的作用都是:产生方法——内联方法,也就是说,省去函数定义,直接写函数体。
Lambda 表达式一般形式:
(input parameters) => {statement;}
其中:
参数列表,可以有多个、一个或者无参数。参数可以隐式或者显式定义。
表达式或者语句块,也就是函数体。
上面代码,第 6 ~ 8 行,没有函数名,是个匿名函数,采用 Lambda 表达式,严格意义上,虽然语法有差异,但目的一样。
示例1:
var baz1 = function() { var foo = 10; var bar = 2; return foo * bar; }; function mutil() { var foo = 10; var bar = 2; return foo * bar; }; alert(baz1()); var baz2 = mutil(); alert(baz2);
说明:
1,baz1 与 baz2 完全一样,但 baz1 与 baz2 相比,省去了函数定义,直接函数体——看上去多简约。
闭包
变量作用域
示例2:函数内部可以访问全局变量。
var baz = 10; function foo() { alert(baz); } foo();
新闻热点
疑难解答
图片精选