局部作用域

局部作用域分为函数作用域块作用域


前言

局部作用域分为函数作用域块作用域

一、函数作用域

        在函数内部声明的变量只能在函数内部被访问,外部无法直接访问。

        eg:

    function fn(){
      let a = 100
      return console.log(a)
    }
    fn()     //运行结果:100
    console.log(a)    //运行结果:Uncaught ReferenceError: a is not defined

         如上所示,变量a无法在函数外部使用。函数执行完毕后,函数内部的变量就会被回收。

        拓展:如果在函数中直接给一个未使用关键字声明的变量赋值,那么这个变量为全局变量,而全局变量一般不会回收,所以我们及其不推荐使用该方法。

二、块作用域

         在JavaScript中使用 { } 包起来的代码称为代码块,代码块内部声明的变量外部有可能无法访问。

为什么要说外部有可能无法访问呢?

解释:比如在ES6之前只有var可以来声明变量,然而用关键字var声明的变量不会产生块级作用域(但是有函数作用域),所以在块级作用域内使用var定义的变量就可以被外部访问到,在ES6新增了let和const,let和const声明的变量会产生块级作用域,所以我们通常使用let和const来声明变量,防止全局变量污染。

我们来看一道题:

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

 那么这道题会输出什么结果呢?

答案是   3 3 3

为什么不是 0 1 2 呢,这道题涉及了异步、作用域、闭包等问题,我们这里暂时先从作用域上分析。

因为 setTimeout 的 console.log(i); 的 i 是 var 定义的,所以是函数级的作用域,不属于 for 循环体,属于 global。等到 for 循环结束,i 已经等于 3 了,这个时候再执行 setTimeout 的三个回调函数(参考js的执行机制https://blog.csdn.net/qq_43141726/article/details/116378073),里面的 console.log(i); 的 i 去向上找作用域,只能找到 global下 的 i,即 3。所以输出都是 3。

解决方法:

这里的解决方法有多种,我们这里给出一种从作用域方向解决的方法:

    for (let i = 0; i < 3; i++) { //把var改成let
      setTimeout(function (){
        console.log(i)
      },1000*i)
    }

let 为代码块的作用域,所以每一次 for 循环,console.log(i); 都引用到 for 代码块作用域下的i,因为这样被引用,所以 for 循环结束后,这些作用域在 setTimeout 未执行前都不会被释放。

 


总结

函数内部声明的变量,在函数外部无法被访问,let 和const声明的变量会产生块作用域,var 不会产生块作用域。

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值