var let const 的区别 ~ 含详细解析

前言

var 、let 和 const 是三个声明变量的关键字,可以用于保存任何类型的数据。每个变量的实质一个用于保存任意值的命名占位符。var 在 ECMAScript 的所有版本中都可以使用,而 const 和 let 只能在 ECMAScript 6 及更晚的版本中使用。


var let const 的区别 (简洁版)

var 关键字:

  1. var 定义变量,可以声明同名变量,可以不进行初始化;(不初始化的情况下保存一个特殊值 undefined )
  2. var 不仅可以改变保存的值,也可以改变值的类型(合法但不推荐);
  3. var 定义的变量在函数作用域内有效;
  4. var 声明变量存在变量提升,var 声明的变量可以挂载在 window 上;

let 声明:

  1. let 定义变量,可以不进行初始化;(不初始化的情况下保存一个特殊值 undefined )
  2. let 不仅可以改变保存的值,也可以改变值的类型(合法但不推荐);
  3. let 用来定义局部变量,仅在块级作用域内有效;
  4. let 不允许重复声明;
  5. 不存在变量提升的现象,所以一定要在定义后使用,否则报错(暂时性死区);
  6. 在全局作用域中用 let 声明变量不会成为 window对象的属性;

const 声明:

  1. const 定义的是常量,必须进行初始化(设置初始值);
  2. const 定义好之后“不能改变”;(不能改变栈里面的数据,堆里面的数据可改变;例如数字不可变,对象的属性等可变)
  3. 仅在块级作用域内有效;
  4. const 不允许重复声明;
  5. 在全局作用域中用 const 声明变量不会成为 window对象的属性;

var let const 详解解析

一、var 关键字:

1、var 定义变量,可以声明同名变量,可以不进行初始化。

可以用它保存任何类型的值,不初始化的情况下会保存一个特殊值 undefined 。

      var message;
      console.log(message); // undefined
      var message = "Hello"; 
      console.log(message);  // hello

2、var 不仅可以改变保存的值,也可以改变值的类型(合法但不推荐);

      var message = "Hello";
      var message = "Hi";
      console.log(message); // hi
      var message = 100;   // 合法但不推荐
      console.log(message); // 100  

3、var 声明的作用域范围,是包含它的函数作用域;

在函数内部:使用 var 定义一个变量,它会成为这个函数的局部变量,函数退出时会被销毁。

      function test(){
        var message = "Hi";
        console.log(message); // hi
      }
      test(); 
      console.log(message); // 出错

在函数内部:去掉之前的 var 操作符之后,message 就变成了全局变量只要调用一次函数test(),就回定义这个变量,并且可以在函数外部访问到。不建议这样做,局部作用域中定义的全局变量很难维护,容易造成困惑;所以严格模式下会直接抛出 ReferenceError

      function test() {
        message = "Hi";
        console.log(message); // hi
      }
      // console.log(message); // 出错
      test();
      console.log(message); // hi

4、var 声名提升:使用 var 声明的关键字会自动提升到作用域的顶部;

      function test() {
        console.log(message); // undefined
        var message = "Hi";
        console.log(message); // hi
      }
      test();

上面的代码因为 var 的声明提升在代码运行时可看做等价于如下代码:

      function test() {
        var message;
        console.log(message); // undefined
        message = "Hi";
        console.log(message); // hi
      }
      test();

5、在全局作用域中用 var 声明变量会成为 window对象的属性;

      var message = "hi";
      console.log(window.message); // hi

6、for 循环中的 var 关键字

var 关键字声明的 for 循环的迭代变量会渗透到循环体的外部,退出循环时迭代变量保存的是导致循环退出的值:5,随后才执行异步函数。

      for (var i = 0; i < 5; ++i) {
        // 循环逻辑
      }
      console.log(i); // 5

      for (var a = 0; a < 5; ++a) {
        setTimeout(() => console.log(a), 0);
      }
      // 你可能会以为会输出0、1、2、3、4
      // 实际上是 5、5、5、5、5

二、let 声明

1、let 定义变量,可以不进行初始化;

不初始化的情况下保存一个特殊值 undefined 

      let a;
      console.log(a); // undefined

2、let 不仅可以改变保存的值,也可以改变值的类型(合法但不推荐);

      let a = 6;
      a = "12";
      console.log(a);  // 12

3、let 用来定义局部变量,仅在块级作用域内有效;

      if (true) {
        var message = "hi";
        console.log(message); // hi
      }
      console.log(message); // hi

      if (true) {
        let name = "哈哈";
        console.log(name); // 哈哈
      }
      console.log(name);  // 未定义

4、let 不允许重复声明;

      var name;
      var name;

      let message;
      let message; // SyntaxError message 已经声明过了

5、不存在变量提升的现象,所以一定要在定义后使用,否则报错(暂时性死区);

      console.log(message); // ReferenceError 未定义
      let message = "hi";

6、在全局作用域中用 let 声明变量不会成为 window对象的属性;

      let message = "hi";
      console.log(window.message); // undefined

7、for 循环中的 let 声明

let 声明的 for 循环的迭代变量时,JS引擎后台会为每个迭代循环声明一个新的迭代变量保存,随后执行异步函数时,引用的都是不同的变量实例。

      for (let a = 0; a < 5; ++a) {
        // 循环逻辑
        setTimeout(() => console.log(a), 0);
      }
      // 输出0、1、2、3、4

      for (let i = 0; i < 5; ++i) {
        // 循环逻辑
      }
      console.log(i); // ReferenceError: i is not defined

三、const 声明

1、const 定义的是常量,必须进行初始化(设置初始值);

      const a; // SyntaxError 

2、const 定义好之后“不能改变”;

不能改变栈里面的数据,堆里面的数据可改变;(例如数字不可变,对象的属性等可变)

      const obj = { name: "哈哈" };
      obj.name = "张三"; 
      console.log(obj); // {name:"张三"}
      const a = 1;
      a = 2; // 报错

3、仅在块级作用域内有效;

      const name = "嘻嘻";
      if (true) {
        const name = "哈哈";
        console.log(name); // 哈哈
      }
      console.log(name); // 嘻嘻

4、const 不允许重复声明;

      const name = "嘻嘻";
      const name = "哈哈";  //报错

5、在全局作用域中用 const 声明变量不会成为 window对象的属性;

      const message = "hi";
      console.log(window.message); // undefined

6、for 循环中的 const 声明

因为const 定义好之后“不能改变”,所以const 在 for 循环中只能声明一个不会被修改的 for 循环变量,这对 for-of 和 for-in 很有意义:

      let i = 0;
      for (const j = 7; i < 5; ++i) {
        console.log(j); // 7,7,7,7,7
      }
      for (const key in { a: 1, b: 2 }) {
        console.log(key); // a,b
      }
      for (const value of [1, 2, 3]) {
        console.log(value); // 1,2,3
      }
      for (const value in [1, 2, 3]) {
        console.log(value); // 0,1,2
      }

通过了解 var、let、const 的特点,

推荐下列两点建议,帮助大家提高代码质量:

1、尽量不使用 var 。限制自己只使用 let 和 const ,因为有了明确的作用域、声明位置,和不变的值,有助于提高代码质量。

2、const 优先,let 次之。const 声明可以让浏览器运行时强制保持变量不变,也可以让代码分析工具提前发现不合法的操作,避免意外发生。只在有意识修改变量时使用 let 。

如有不同见解,欢迎讨论,更多内容,正在更新中。。。。。。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

旺旺大力包

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值