javascript中变量let var const

看书……摘抄


var关键字
  1. var声明作用域

使用var操作定义的变量会成为包含它的函数的局部变量,在函数内部定义一个变量,就意味着该变量将在函数退出时被销毁

       (function test(){
            var x='hello'
            y='how are you?'// 全局变量y
        })()
        //y未使用var定义,全局可访问
        console.log(y);//how are you?

		//在函数外部打印x,x是函数内部的局部变量,外部无法访问
        console.log(x);//x is not defined,控制台报错

在这里插入图片描述在函数外部打印x,x是函数内部的局部变量,外部无法访问

  1. var声明提升

使用var关键字声明的变量会自动提升到函数作用域顶部

    // 执行函数不会报错,var 声明的变量提前,但是还没赋值
        function foo(){
            console.log(age);
            var age=12;

            /* 等价于
            var age;
            console.log(age);
            age=12;
            */
        }
        foo()//undefined

在这里插入图片描述

let声明

let和var的作用差不多,但是二者最明显的区别是,let声明的范围是块作用域var声明的范围是函数作用域

  if(true){
            let age=14
            console.log(age);//14
          }
        console.log(age);//ReferenceError: age is not defined
  1. age变量之所以不能在if块外部被引用,是因为let作用域仅限于该块内部,块作用域是函数作用域的子集。var作用域也是如此。
  2. 而且let不允许同一个块作用域中出现冗余声明,这样会导致报错。但是var可以。
  1. 暂时性死区

let和var的另一个重要的区别:就是let声明的变量不会在作用域中被提升

       // 暂时性死区
        console.log(name);//undefined
        var name='user'

        console.log(age);//ReferenceError: Cannot access 'age' before initialization
        let age=18

在这里插入图片描述

  1. 全局声明

let在全局作用域中声明的变量不会成为window对象的属性,但是var声明的变量可以。

        // 全局声明
        var name='Maria'
        console.log(window.name);//Maria

        let age=19
        console.log(window.age);//undefined

在这里插入图片描述

  1. 条件声明

在使用 var 声明变量时,由于声明会被提升,JavaScript引擎会自动将多余的声明在作用域顶部合并为一个声明。因为 let 的作用域是块,所以不可能检查前面是否已经使用 let 声明过同名变量,同时也就不可能在没有声明的情况下声明它。

  1. for循环中的let声明

在let出现之前,for循环定义的迭代变量会渗透到循环体外部

     for(var i=0;i<5;i++){
            // 逻辑……
         }
        console.log(i);//5
  • 使用let之后:
  for(let j=0;j<5;j++){
            // 逻辑……
    }
        console.log(j);//ReferenceError: j is not defined

在这里插入图片描述

使用var的时候,最常见对迭代变量的奇特声明和修改:

   for(var i=0;i<5;++i){
           setTimeout(() => {
               console.log(i);//5 5 5 5 5  var改成let的时候打印的就是0 1 2 3 4
           }, 100);
        }

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

原因:

  1. var声明的迭代变量: 在退出循环时,迭代变量保存的是导致循环退出的值:5。 在之后执行超时逻辑时,所有的i都是同一个变量,最后输出的都是同一个最终值。
  2. 使用let声明迭代变量: JavaScript在后台会为每个迭代循环声明一个新的迭代变量, 每一个settimeout引用的都是不同的变量实例,所以输出的就是循环执行过程中每个迭代变量的值。
const声明
  1. const的行为与let基本相同,唯一一个重要的区别是用它声明变量时必须同时初始化变量,且尝试修改const变量会导致运行时错误。
  2. const声明的限制只适用于它指向的变量的引用,如果const变量引用的是一个对象,那么修改这个对象内部的属性并不违反const的限制。
  • const声明的number/string/null/undefined数据类型不可以再改变其值,但是对象可以改变。
  • 非对象类型的不可以修改
  const name='admin'
  name='user'//Identifier 'name' has already been declared
  
  //const声明的作用域也是块
 	const age=12
        if(true){
            const age=18
        }
  	console.log(age);//12

在这里插入图片描述

 for(const i=0;i<10;++i){
      console.log(i);//结果是打印:0 并且报错  TypeError: Assignment to constant variable.
    }

打印结果是0 ,并且报错,在++i的时候报错,非对象不可修改。

  • 对象可以改变:
  const obj={name:'这是一个对象'}
  obj.name='对象可以修改内部属性'
  console.log(obj);//对象可以修改内部属性

小结

最佳实践

  1. 不适用var
  2. const优先,let次之。const声明可以让浏览器运行时强制保持变量不变,也可以让静态代码分析工具提前发现不合法的赋值操作,在提前知道未来会有修改时,再使用let。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值