深入理解JavaScript作用域、变量对象、闭包

几个月前用到了js,想深入理解js,汤姆大叔http://www.cnblogs.com/TomXu/archive/2011/12/15/2288411.html是个好东西,可惜第一遍看的时候津津有味,感觉懂了,几个月没用js就记不得细节了,翻来覆去看了几遍,钻深了以后总感觉有不会的地方。做一个记录,有想法就记下来。

在知乎下写过一点

先举个例子,说明为什么要用闭包
var data = [];
for (var k = 0; k < 3; k++) {
data[k] = function () {
alert(k);
};
}
data[0](); // 3, 而不是0
data[1](); // 3, 而不是1
data[2](); // 3, 而不是2

一目明了,使用闭包之后

var data = [];
for (var k = 0; k < 3; k++) {
data[k] = (function _helper(x) {
return function () {
alert(x);
};
})(k); // 传入"k"值
}
// 现在结果是正确的了
data[0](); // 0
data[1](); // 1
data[2](); // 2
这个例子可以回答'什么样的需求下才需要闭包?
浏览本问题的应该都是像我一样的js小白,都体会过面对晦涩文字的沮丧,所以写的时候尽量通俗易懂,做入门之用。
要搞明白闭包,先要弄清楚闭包的七大姑八大姨——作用域链(scope chain)、变量对象(variable object)、执行环境(execution contexts)。
var x = 10;
function foo() {
alert(x);
}
(function () {
var x = 20;
foo(); // 10, but not 20
})();
即使20小兄弟离foo这么近,在一个括号里面,foo()还是10?
到底是为什么呢?这就要讲到变量对象和执行环境。
在上面这个例子中:
foo()是一个申明,(function(){})是一个表达式,(function(){})()是表示自运行函数;
全局上下文的变量对象是:
globalContext.VO === Global = {
  x: 10
  foo: <reference to function>
};
在“foo”创建时,“foo”的[[scope]]属性是:
foo.[[Scope]] = [
  globalContext.VO
];
在“foo”激活时(匿名函数调用),“foo”上下文的活动对象是:
fooContext.AO = {
没有
};
“foo”上下文的作用域链为:
fooContext.Scope = fooContext.AO + foo.[[Scope]] // i.e.: 
fooContext.Scope = [
  fooContext.AO,
  globalContext.VO
];
x=20不会出现在foo的作用域链;
这个例子也清晰的表明,一个函数(这个例子中为从函数“foo”返回的匿名函数)【我认为应该是从匿名函数返回的“foo”函数】的[[scope]]持续存在,即使是在函数创建的作用域已经完成之后。
接下来就要分析data[k]()这个例子的作用域链了,我还没搞明白

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值