JavaScript作用域

JavaScript作用域

  1. 作用域:变量可作用的区域
    • 全局作用域:在函数以外的区域
    • 私有作用域:以函数为划分的区域
  2. 作用域链:函数会限制变量的作用域范围,而函数内是可以再嵌套函数的,函数的层层嵌套,就形成了一个作用域链。
  3. 当函数内使用某个变量的时候,会按照如下过程找到该变量:
    1. 先从自身所在作用域去查找,如果没有再从上级作用域当中去查找,直到找到全局作用域当中。
    2. 如果其中有找到,就不会再往上查找,直接使用。
    3. 如果都没有找到,那么就会报引用错误提示变量没有定义。
  4. 如果在函数内部声明的变量没有使用关键字就会被挂到 window 上。
  5. 20220328121354
  6. 20220328124553
  7. 变量提升:预解析、预编译
    • var 只声明不定义
    • function 既声明又定义
  8. 预编译:
    1. 生成 AO 对象;
    2. 把形参和变量声明的名作为 AO 对象的属性名,值统一;
    3. 实参值传到形参当中;
    4. 在函数体找函数声明,值赋予函数体;
  9. 全局预编译:
    1. 生成 Go 对象;
    2. 把形参和变量声明的名作为 AO 对象的属性名,值统一;
    3. 实参值传到形参当中;
    4. 在函数体找函数声明,值赋予函数体;
  10. return:下面的代码虽然不执行,但是变量会提升,下面的代码进行变量提升,return 后面的代码不进行变量提升
        function fn(){
            console.log(a);
        return function f1(){
        }
            var a=3;
        }
        fn();
    
  11. 如果预编译进入 if 语句时 var 和 function(函数)都是只声明不提升
  12. 自执行函数在当前所在的作用域中不进行变量提升,自执行函数自己所形成的私有作用域照常进行
        function f2(){
            console.log("f2");
        }
        // 自执行函数在此处不进行变量提升
        (function (){
            console.log(a);// undefined, 照常进行变量提升
            var a=3;
        })();
    
  13. 判断一个对象有没有该属性用 in"d" in window//判断window中有没有d;
  14. let 和 const 这两个是没有变量提升的都是声明一个变量

const 声明的变量指针是不能改的const num = 300; num = 200;会报错

  1. const 声明变量必须赋值否则会报错const num//会报错,没有初始值
  2. 在全局上下文中,基于 var 声明的变量是直接放在 GO(window)中,而基于 let 声明的变量是放在 VO(G)中 的,和 GO 没关系
  • var 存在的变量提升,let 不存在变量提升
  • var 允许重复声明,而 let 是不允许的[而且在词法分析阶段就过不去]
  • let 会产生块级上下文,var 不会
  • 关于暂时性死区问题:typeof 检测一个未声明的变量,不会报错,结果是 undefined 在 let 声明前使用就会报错
    20220329105827

    但是在加入了块级作用域的时候 let 和 const 之后,在其被声明之前对块中的 let 和 const 进行 typeof 操作会报错

    • ECStack:execution context stack 执行环境栈
  • heap:堆
  • VO(G):variable object stack 执行环境栈
  • GO:Global object 全局对象
  • AO:Activation Object 执行上下文
  1.       console.log(a, b);//undefined undefined
          var a = 12,
              b = 12;
          function fn() { // undefined 12
              console.log(a, b);
              var a = b = 13;
              console.log(a, b); // 13 13
          }
          fn();
          console.log(a, b); // 12 13
    
    

20220329115928
18. 电脑显卡挂壁了,准备去修电脑,新电脑坑爹



闭包
  1. 全局栈内存页面关闭是会被释放,普通函数一般调用结束会被释放

  2. 闭包让你可以在一个内层函数中访问到其外层函数的作用域

  3. 闭包什么时候产生?

    1. 函数嵌套函数
    2. 被嵌套的函数内部引用了外部函数的形参或者变量
    3. 外部函数被调用
    • 优点:
    1. 延长了局部变量的生命周期
    2. 可以通过闭包实现一些高级一点的功能
  4. 用 setTimeout 实现 setInterval

  function fn(){
      console.log(666);
      setTimeout(()=>{
          fn()
      },1000)
  }
  fn();
  1. 同步先执行,完成之后再执行异步
  2. 上级作用域:就是看这个函数是在哪个作用域创建的
  3. 全局变量:全局作用域下的变量;私有变量:私有作用域下的变量(形参,私有作用域下声明的变量)
  4. 预编译:函数形成一个私有作用域,形参赋值–>变量提升–>代码从上到下执行
  5. let 和 const 在声明之前都是不能使用的,如果使用会进入暂时性死区
  6. 20220330105817
  7. let 不能重复声明,能识别块级作用域,有暂时性死区
  8. const 声明的是一个常量,其他等同于 let
  9. this 执行主体:谁让这个函数执行。
    • 全局下的 this 是 window
    • 事件绑定高中对应的函数的 this 是绑定的那个函数
    • 箭头函数中没有 this 和 arguments,他是把这两个关键字当做普通变量去对待。
  10. 函数执行,里面的 this 是谁就看执行前边有没有点,点前面是谁 this 就是谁,没点就是 window
  11. 自执行函数中的 this 就是 window
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值