javascript中的function都关联到作用域链(scope chain),scope chain作为它的内部状态被保存下来。function的scope chain是其定义时的作用域,而不是调用时的作用域。闭包指的function,加上它保存在内部的,定义该function时的scope chain
一般情况下,function定义和调用的作用域一样,这种情况比较好理解
function outter(){ var text = "hello"; function inner(){ console.log(text); } inner(); } outter();// hello
var scope = "global scope"; function outter(){ var scope = "local scope"; function inner(){ console.log(scope); } return inner; } outter()();// local scope
外围函数每调用一次,就产生一个新的scope chain(其中每次都包含新的call object),因此产生的每个闭包的scope chain都是私有的,不互相干扰。下面的例子是一个错误的写法:
var funcs = []; function createClosure(){ for(var i = 0; i < 5; i++){ funcs.push(function(){ return i; }) } } createClosure(); for(var i = 0; i < 5; i++){ console.log(funcs[i]());// all 5 }
var funcs = []; function createClosure(i){ funcs.push(function(){ return i; }) } for(var i = 0; i < 5; i++){ createClosure(i); } for(var i = 0; i < 5; i++){ console.log(funcs[i]());// 0, 1, 2, 3, 4 }
另外要注意的是,this和arguments比较特殊
this是关键字,并不是临时变量,所以不是保存在scope chain上,如果内部的函数要保留外部函数的this,需要把this赋值给一个临时变量
function outter(){ var self = this; return function(){ return self; } } outter()();// global console.log(outter()() == global);// true
function outter(name){ var outterArguments = arguments; return function(){ return outterArguments[0]; } } console.log(outter("kyfxbl")());// kyfxbl