Promise、闭包、作用域、作用域链

一、Promise

1.promise是什么?

异步编程的解决方案

2.promise的出现?

解决异步编程的回调地狱问题

3.promise详解

promise是一个对象,代表一个异步操作,它有两个特征,三种状态(pengding、fulfilled/resolved、rejected),两个状态改变结果,即resolve和rejecte方法,它的原型上有then、catch、finally方法

4.promise与async/await

  • async/await是消灭异步回调的终极武器,与promise相辅相成,async写在函数前边,await写在异步请求api函数前面,后面跟的promise
  • 执行async函数返回的一定是promise对象,
  • 在async修改的函数内部return一个值,可以在then回调函数中拿到
  • await相当于promise的then,try…catch相当于promise的catch
  • 首先,无法取消Promise,一旦新建它就会立即执行,无法中途取消。
  • 其次,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部

二、闭包

  • 定义:能够访问到其他函数作用域中的对象的函数,称为闭包
    在这里插入图片描述

  • 什么是回调函数(callback)?

回调是作为参数传递给另一个函数并在其父函数完成后执行的函数

<script>
      function doSomething(msg, callback) {
          alert(msg);
          if (typeof callback == "function")
              callback();
      }
      doSomething("回调函数", function() {
          alert("匿名函数回调!");
      });
  </script>
  <script>
      //定义主函数,回调函数作为参数
      function A(callback) {
          callback();
          console.log('我是主函数');
      }
      //定义回调函数
      function B() {
          setTimeout("console.log('我是回调函数')", 3000); //模仿耗时操作
      }
      //调用主函数,将函数B传进去
      A(B);
  </script>
  • 分析过程
  1. 全局执行上下文创建作用域链,作用域链包含了全局变量对象 [作用域链:[全局变量对象]]

  2. books函数调用时创建作用域链,具体操作为先复制全局的作用域,然后创建活动对象AO推入当前作用域的顶端 [作用域链:[book活动变量, 全局变量对象]],books函数执行完毕后当前作用域会被销毁

  3. bag函数调用创建作用域,首先复制上层作用域[作用域链:[book活动变量, 全局变量对象]],然后创建活动对象AO推入当前作用域的顶端[作用域链:[匿名函数func, book活动变量, 全局变量对象]],bag函数执行完毕后当前作用域会被销毁
    在这里插入图片描述
    在这里插入图片描述

  • 闭包为什么会造成内存的泄露?

内存的泄露指应该被清除而没有被清除
能够访问到其他函数作用域中的对象的函数,称为闭包

面试中常问到的问题

1.如何在外部访问函数作用域内的变量,请手写一段代码进行验证
2.分析一道面试题

// function fn() {
//     var arr = []
//     for (var i = 0; i< 10; i++) {
//         arr[i] = function() {
//             return i
//         }
//     }
//     return arr
// }

function fn() {
    var arr = []
    for (var i = 0; i< 10; i++) {
        (function(i){
            arr[i] = function() {
                return i
            }
        })(i)
    }
    return arr
}
var arr = fn()
console.log(arr[0]())
var arr = fn()
console.log(arr[0]())

在这里插入图片描述

  • 自调用函数?

自调用函数即立即执行函数,多个立即执行函数需要加分号

(function(){})() //写法1:括号外调用
(function(){}()) //写法2:括号内调用

三、作用域

简记忆:作用域规定了能够被访问的范围,分全局、局部(函数)、、

ES6中的全局作用域

在这里插入图片描述

ES6中的局部(函数)作用域

在这里插入图片描述
在这里插入图片描述

ES6中的块级作用域

//es6前js没有块级作用域
if (true) {
    var a = 1 //ES6之前使用var声明的变量会存在变量提升,它们的作用域是函数作用域或者全局作用域.即// window.a
}
console.log(a) //结果:1


function fn () {
    if (true) {
        var a = 2 //变量a只存在于if语句块内部,所以在块外部无法访问
    }
    console.log(a) //结果:undefined
}
//es6后引入了let和const关键字,它们可以在声明的块(如if语句、for循环等)内创建块级作用域,与其他作用域一样,对外是不可见的

if (true) {
    let x = 1  //使得代码更加可控和可靠。开发者可以更好地管理变量的作用域,避免变量冲突和意外的副作用
}
console.log(x) //结果: Uncaught ReferenceError: x is not defined

四、作用域链

作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有序访问。

var a = 1
function fn () {
  var b = a + 1
  console.log(b)
}
fn()

从代码执行来看

首先在创建fn函数时,会创建一个预先包含全局变量对象的作用域链,这个作用域链被保存在内部的[[Scope]]属性中。/当调用fn函数时,会为函数创建一个执行环境,然后通过复制函数的[[Scope]]属性中的对象构建起执行环境的作用域链,然后创建活动对象AO并推入执行环境的作用域链。/在fn执行完成后,作用域就会被销毁。
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值