JavaScript.The.Good.Parts阅读笔记(二)作用域&闭包&减缓全局
2024-05-06 14:26:44
供稿:网友
如代码块
代码如下:
if (true) {
int i = 100;
}
print(i); //错误,变量i没有声明
如上面例子所示,代码块外的函数是无法访问i变量的。
但在javaScript里,情况则完全不同。
代码如下:
if (true) {
var i = 100;
}
alert(i); //弹出框并显示100
很多现代语言都推荐尽可能迟地声明变量,但在Javascript里这是一个最糟糕的建议。由于缺少块级作用域,最好在函数体的顶部声明函数中可能用到的所有变量。
闭包特性:
虽然缺少块级作用域,但是函数的作用域还是存在的。
这种作用域有一个好处,就是内部函数可以访问定义它们的外部函数的参数和变量(除了this和argument)。
利用这种特性,则可以这样来设计代码。
代码如下:
var bankAccount = function () {
var value = 0;
return {
deposit: function (inc) {
value += inc;
},
getValue: function (){
return value;
}
}
}
var myAccount = bankAccount(); //新开一个银行账户
myAccount.deposit(1000); //存1000块进去
alert(myAccount.getValue()); //should alert(1000);
value由于在bankAccount这个function里,外部无法对它进行直接操作,必须通过bankAccount function给他返回的对象来进行操作,通过这样来实现C#和java里的private的字段。
减缓全局变量污染全局空间:利用函数的作用域,我们在写js库的时候可以减少跟其他库冲突。
代码如下:
(function () {
var hello = 'Hello World.';
})();
alert(hello); //error: hello no exist.
这里的语法很有点诡异,主要思想是定义一个匿名方法,并且马上执行。由于function开头这个litertal会被解释作为函数定义,这里加上了一对括号包住它,然后再用一对括号表示调用此函数。外部的alert访问不到在函数内部定义的hello。
陷阱一:var的陷阱
“减缓全局变量污染全局空间”的例子改成
代码如下:
(function () {
hello = 'Hello World.'; //remove var
})();
alert(hello); //alert ('Hello World.');
当变量hello没有用var显式声明时,hello成为了一个全局变量!!
虽然利用这个特性,咱们可以提供一个对外接口,但不建议这样做。
代码如下:
(function () {
var hello = 'Hello World.';
sayHello = function () { //不建议采用这种方式来提供接口,看起来很不明显。
alert(hello);
}
})();
sayHello();
可以改进为
代码如下:
(function (window) {
var hello = 'Hello World.';
window.$ = {
sayHello: function () {
alert(hello);
}
};
})(window);
$.sayHello(); //看起来像jQuery那么酷
或
代码如下:
var obj = (function () {
var hello = 'Hello World.';
return {
sayHello: function () {