js闭包详谈


js闭包详谈

闭包的定义很简单:函数 A 返回了一个函数 B,并且函数 B 中使用了函数 A 的变量,函数 B 就被称为闭包。

function A() {
  let a = 1
  function B() {
      console.log(a)
  }
  return B
}

循环中使用闭包解决 var 定义函数的问题

for ( var i=1; i<=5; i++) {
    setTimeout( function timer() {
        console.log( i );
    }, i*1000 );
}
  • 首先因为 setTimeout 是个异步函数,所有会先把循环全部执行完毕,这时候 i 就是 6 了,所以会输出一堆 6
  • 解决办法两种,第一种使用闭包
for (var i = 1; i <= 5; i++) {
  (function(j) {
    setTimeout(function timer() {
      console.log(j);
    }, j * 1000);
  })(i);
}
  • 第二种就是使用 setTimeout 的第三个参数
for ( var i=1; i<=5; i++) {
    setTimeout( function timer(j) {
        console.log( j );
    }, i*1000, i);
}

第三种就是使用 let 定义 i

for ( let i=1; i<=5; i++) {
    setTimeout( function timer() {
        console.log( i );
    }, i*1000 );
}

因为对于 let 来说,他会创建一个块级作用域,相当于

{ // 形成块级作用域
  let i = 0
  {
    let ii = i
    setTimeout( function timer() {
        console.log( i );
    }, i*1000 );
  }
  i++
  {
    let ii = i
  }
  i++
  {
    let ii = i
  }
  ...
}

文章作者: 曹豆芽
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 曹豆芽 !
 上一篇
深浅拷贝 深浅拷贝
深浅拷贝浅拷贝 首先可以通过 Object.assign来解决这个问题,很多人认为这个函数是用来深拷贝的。其实并不是,Object.assign 只会拷贝所有的属性值到新的对象中,如果属性值是对象的话,拷贝的是地址,所以并不是深拷贝 let
2020-03-03
下一篇 
vue使用axios vue使用axios
vue使用axios1.在mina.js中写下面代码 import Axios from "axios"; Vue.prototype.HOST = "http://localhost:4000";
2020-03-01
  目录