Skip to content

理解JavaScript的闭包 #6

Open
@lfb

Description

@lfb

闭包

MDN对闭包的定义:闭包是指那些能够访问自由变量的函数。自由变量是指在函数中使用的,但既不是函数参数也不是函数的局部变量的变量。

闭包 = 函数 + 函数能够访问的自由变量。

比如:

var a = 10;

function fn1() {
    conosoe.log(a);
}
fn1(); // 变量a是全局作用域的,fn1 可以访问到自由变量a,输出1

再修改一下

function fn1() {
  var a = 10;

  var fn2 = function () {
    return a;
  }
  return fn2
}

fn1()(); // 10

a 是fn1内部的变量,在全局作用域是无法访问的,fn2 的父级作用域有fn1,fn2可以访问到自由变量a,然后通过函数返回的方法,在全局作用域下也能“访问”到了a变量,这可以理解为闭包。

用闭包解决for循环的问题

for (var i = 0; i < 5; i++) {
  setTimeout(function () {
    console.log(i); // 连续输出 5
  }, 0);
}

原因是setTimeout是异步,当for循环代码执行完后才执行异步代码,此时异步代码里面的函数去找自由变量i,此时i的结果都是5了。

解决方法:

for (var i = 0; i < 5; i++) {
  (function (j) {
    // console.log(j); 
    setTimeout(function () {
      // 每个立即执行函数都保存着自己作用域的参数 j 的值,异步调用函数时,访问的是自由变量 j
      console.log(j); 
    }, 0);
  })(i);
}

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions