js中什么是作用域和变量提升以及 var、let和const的作用与区别

在了解var,let,const的区别与作用时,首先得知道什么是作用域和变量提升

块级作用域:也叫局部作用域,js在es5之前,只有函数存在局部作用域,局部作用域下的变量,只会在当前作用域下进行访问和修改,在他之外是无法进行访问和修改的

    function fn (){
      var num = 100;
    }
    console.log(num);//ReferenceError 引用类错误,num没有定义

全局作用域:在整个script标签里都可以进行访问与修改

变量提升:js在代码执行前,系统会将所有的变量进行变量初始化(var 变量名;)

    console.log(str); //undefined
    var str = '我是js';
    console.log(str); //我是js

造成第一次打印为undefined的原因就是因为此时的场景为

    var str;
    console.log(str); //undefined
    var str = '我是js';
    console.log(str); //我是js

而函数内部同样存在变量提升

    var num = 10;
    function fn (){
      console.log(num); //nudefined
      var num = 100;
    }
    fn();

而造成num为undefined的原因为:函数内部会再一次对变量进行初始化,而js的运行机制为,会优先考虑当前作用域下的变量,所以导致了num为undefined

var

用var声明的变量或函数,有变量提升,而且用var声明的变量没有块级作用域

let

let为es6新增,用let声明的变量,首先最大区别与var是,let拥有了块级作用域,其次,let没有变量提升另外,在for循环中,用let声明迭代变量,变量值会被值锁定

块级作用域体现:

    if(true){
      let num1=100;
      var num1=200;
    }
    console.log(num1);//ReferenceError 引用类错误,num没有定义
    console.log(num2);// 200

没有变量提升体现:

    console.log(num1);//ReferenceError 引用类错误,num没有定义
    let num1 = 100;
    console.log(num1);//100

变量值锁定体现:

    for(var i = 0;i<=4;i++){
      setTimeout(() => {
        console.log(i);
      }, 0);
    }

你会认为会打印的是0,1,2,3,4而实际打印的却是4,4,4,4,4,造成这一原因是因为,for循环是同步的,而定时器为异步函数,所以当定时器调用时,for循环已经跑完了,里面的i值已经为迭代变量i退出循环的值4了

在es6之前,常用解决这种问题的方法为

    for(var i = 0;i<=4;i++){
      (function(_index){
        return  setTimeout(() => {
          console.log(_index);
        }, 0);
      })(i);
    }

原理为在每一次循环进行时,自己调用一个函数并且把i作为参数传入,而函数是有块级作用域的,所以,每一次传入的i值将会被牢牢锁定在当前作用域下,以达到接下来说说明的let的变量值锁定效果

es6解决办法

    for(let i = 0;i<=4;i++){
      setTimeout(() => {
        console.log(i); //0,1,2,3,4
      }, 0);
    }

暂时性死区:因为let与const没有变量提升所以在这之前访问都会报Uncaught ReferenceError/未捕获引用错误,在这一区域被称为'暂时性死区'

const

const与let的效果近似,区别在于用const声明的变量,变量的值无法改变

    const str = "我是JavaScript";
    console.log(str = 100); //TypeError 无法捕获类型错误 不能对常量进行修改

但是,通过const声明的数组,对象,以及函数里面的值,是可以进行修改的,所以,const一般用于声明这类类型所提供的

    const myarr = [100,200];
    myarr.push(300);
    console.log(myarr);//[100, 200, 300]
    const obj = {
      num1:1,
      num2:2
    }
    obj.num1 = 100;
    console.log(obj.num1); //100

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值