初步了解闭包

来源:互联网 发布:苹果特效相机软件 编辑:程序博客网 时间:2024/06/05 21:54

初步了解JS中的闭包

  • 闭包就是当内部函数需要使用外部函数定义的变量时,就会产生闭包,闭包就是一个可以访问外部函数定义变量的函数
  • 闭包会使得函数内部变量保存在内存中,内存消耗很大,所以不能滥用闭包
  • 在IE中可能导致内存泄露,解决方法,在退出函数之前,将不使用的局部变量删除

在理解闭包之前,你需要知道一些JavsScipt的基本知识

全局
直接在<script></script>标签下声明的变量的 –>全局变量
var a = “hello” ; alert(a);
全局变量和函数都是window的一个属性,都能通过window.变量名访问

局部
每一个函数都会生成一个局部的域,函数内声明的变量
function fn(){ var b = “word”;} –> b为局部变量 外部无法访问

作用域链
局部可以访问全局(局部)变量 从内到外 –> 向上寻找
内部变量会覆盖外部变量
如果内部和外部有相同的形参,声明标量,那么修改的是和访问的形参,声明标量—->就近原则

  • 再来看看闭包
    当function里嵌套function时,内部的function可以访问外部function里的变量。

function foo(x) {
  var tmp = 3;
    function bar(y) {
     alert(x + y + (++tmp));
     }
   bar(10);
 }
foo(2)

不管执行多少次,都会alert 16,因为bar能访问foo的参数x,也能访问foo的变量tmp。
但,这还不是闭包。当你return的是内部function时,就是一个闭包。内部function会close-over外部function的变量直到内部function结束。

function foo(x) {
  var tmp = 3;
    return function (y) {
      alert(x + y + (++tmp));
   }
}
var bar = foo(2); // bar 现在是一个闭包
bar(10);

上面的脚本最终也会alert 16,因为虽然bar不直接处于foo的内部作用域,但bar还是能访问x和tmp。
但是,由于tmp仍存在于bar闭包的内部,所以它还是会自加1,而且你每次调用bar时它都会自加1

来测试一下

function fun(n,o) {
  console.log(o)
   return {
   fun:function(m){
   return fun(m,n);
  }
 };
}

var a = fun(0); a.fun(1); a.fun(2); a.fun(3);//?,?,?,?
var b = fun(0).fun(1).fun(2).fun(3);//?,?,?,?
var c = fun(0).fun(1); c.fun(2); c.fun(3);//?,?,?,?

var a = fun(0); a.fun(1); a.fun(2); a.fun(3);

/*
fun(0)调用的第一层 a.fun(1),a.fun(2),a.fun(3)调用的第二层
fun(0) – m = 0 ;o =undefined; n = 0;
a.fun(1) m = 1 ; n = 0 第二层的返回值 fun(1,0) 返回第一层fun(n,o); o=0;
a.fun(2) m = 2 ;n= 0 第二层的返回值 fun(2,0) 返回第一层fun(n,o); o=0
a.fun(3) m = 3 ;n= 0 第二层的返回值 fun(3,0) 返回第一层fun(n,o);o=0
*/
var a 的返回值为 undefined,0,0,0

var b = fun(0).fun(1).fun(2).fun(3);
/*
fun(0)调用的第一层 n = 0; fun(0,undefined)
fun(1)调用第二层 m = 1 n = 0,并且获取第一次fun(0)返回的n的值 返回第一层 fun(n,o) –>fun(1,0)
fun(2)调用第二层并且获取fun(1)返回的n的值; m = 2 ; n = 1 返回第一层fun(n,o) –>fun(2,1)
fun(3)调用第二层并且获取fun(2)返回的n的值; m= 3 ;n=2;返回第一层fun(n,o) –> fun(3,2)
*/
var b 返回的值为 undefined,0,1,2

var c = fun(0).fun(1); c.fun(2); c.fun(3);//?,?,?,?*
/*
fun(0) 调用第一层 fun() n=0 o = undefined;
fun(1) 调用第二层并且获取第一次fun(0)的返回值n; m = 1 ;n =0 返回第一层fun(n.o) –>fun(1,0)
fun(2) 调用第二层并且获取第二次fun(1)的返回值n; m = 2 ;n=1 返回第一层fun(n,o) –> fun(2,1)
fun(3) 调用第二层并且获取第二次fun(1)的返回值n; m = 3 ; n= 1 返回第一层fun(n,o) –>fun(3,1)
*/
var c 的返回值为 undefined,0,1,1;

原创粉丝点击