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

    xiaoxiao2021-03-25  197

    几个月前用到了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]()这个例子的作用域链了,我还没搞明白
    转载请注明原文地址: https://ju.6miu.com/read-463.html

    最新回复(0)