你不知道的JS阅读笔记——(2)提升和闭包

1、提升

函数声明提升的优先度比变量提升的优先度要高
函数表达式不会提升

2、闭包

2.1 简介

函数内声明函数可以说是闭包,但准确的来说并不是。
闭包:某函数在声明的作用域外被调用并且能够阻止「原作用域」的销毁,以及使用原作用域内的变量
闭包和块作用域结合是最屌的

var result = [];
var a = 3;
var total = 0;

function foo(a) {
    //3.这里如果被改为let i 将会是绝杀,可惜改不得,因为let会在每一次的迭代里面生成一个封闭的作用域
  for (var i = 0; i < 3; i++) {
    result[i] = function () { //2.因为这里的闭包都有一个共享的作用域,i就在那个被共享的作用域里
      total += i * a; //1.这里还没有调用,所以不用急着赋值,只是指定了result 的每一项是一个函数,函数有这个功能
      console.log(total);
    }
  }
}

foo(1);
//2.这里才调用闭包函数 此时foo函数里的for循环已经执行完毕,i已经被定为3
result[0](); // 3  
result[1](); // 6
result[2](); // 9

2.2 闭包的作用

闭包可以阻止作用域被销毁
也可以把一些函数内的值保存下来。闭包可以实现方法和属性的私有化,比如生成一个模块,看书p56

2.3 闭包经典使用场景

2.3.1 return 回一个函数

function foo() {
  var a = 2;
  function bar() {
    console.log(a);
  }
  return bar;
}

var baz = foo();

baz(); // 2

2.3.2 IIFE(自执行函数)

this指向全局作用域

(function (a) {
  console.log(a);
})(1)

2.3.3 循环赋值

settimeout里的回调函数的this指向全局作用域

for(var i = 0; i<10; i++){
  (function(j){
       setTimeout(function(){
        console.log(j)
    }, 1000) 
  })(i)
}

因为存在闭包的原因上面能依次输出1~10,闭包形成了10个互不干扰的私有作用域。将外层的自执行函数去掉后就不存在外部作用域的引用了,输出的结果就是连续的 10。为什么会连续输出10,因为 JS 是单线程的遇到异步的代码不会先执行(会入栈),等到同步的代码执行完 i++ 到 10时,异步代码才开始执行此时的 i=10 输出的都是 10。

2.3.4 回调函数

setTimeout(function(){
  console.log(j)
}, 1000) 

…见参考文章

参考文章:关于 JS 闭包看这一篇就够了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值