深入理解JavaScript闭包

2017-04-17  本文已影响0人  LeeYee11

作用域

function foo(){
  a=1
  var b=1;
}
foo();
console.log(a);//1
console.log(b);//ReferenceError: b is not defined
i=999;//全局变量
function foo(){
  var i=233;//局部变量
  console.log(i);
}
foo();//233
console.log(i);//999
for(var i=0;i<10;i++){ //此处的i为全局变量i
  console.log(i);//1 2 3 4 5 6 7 8 9
}
console.log(i);//10
var a=1;
function foo(){
  a=2;
  var b=2;
}
foo();
console.log(a);//2
console.log(b);//ReferenceError: b is not defined
function foo(){
  var a=1;
  function bar(){
    console.log(a);
  }
  bar();
}
foo(); //1
function foo(){
  var a=2;
  function bar(){
    console.log(a);
  }
  return bar;
}
var getResult=foo();
getResult();

闭包

function foo(){
  var i=1;
  function getI(){
    return i;
  }
  return getI;
}
console.log(i);//undefined
var GI=foo();
var i=GI();
console.log(i);//i
function foo(){
  var i=1;
  function getI(){
    return ++i;
  }
  return getI;
}
var GI=foo();
var i=GI();
console.log(i);//2
i=GI();
console.log(i);//3
//说明此处依然是调用的foo的缓存
//因为getI赋值给了全局变量GI,getI又依赖于foo,所以GI存在时foo就不会
被回收

总结

function foo(){
  var i=1;
  return function(a){
    i+=a;
    return i;
  }
}
var add=foo();
console.log(add(0));//1
console.log(add(5));//6
var foo={
  i:1,
  add:function(a){
    that=this;
    return (function(){
      return that.i+a;
    })()
  },
  getI:function(){
    return (function(){
      return this.i;
    )()
  }
}
var f=foo;
console.log(f.add(0));
console.log(f.getI());
console.log(f.add(5));
//一道经典的面试题
for(var i=0;i<3;i++){
  setTimeout(function(){
    alert(i)
  },2000)
}
//实际弹出的是3 3 3,而非0 1 2
//因为setTimeout()中执行的函数会放置到另一个队列里面执行
//此时i早已变为3,当alert再执行时,会往上一个作用域中找i
//此时弹出的就是3 3 3

//解决办法如下
for(var i=0;i<3;i++){
  (function(e){
    /*** 该作用域的e依赖外层作用域的i ***/
     setTimeout(function(){
       alert(e)
    },2000)
    /*** 作用域结束 ***/
  })(i);
}
//构造闭包,使循环赋值给e(即i的引用)

参考

学习Javascript闭包(Closure)

上一篇下一篇

猜你喜欢

热点阅读