var,let,const关键字声明变量的区别

1.作用域

var没有块级作用域,而let和const声明的范围是块作用域。 一对大括号就是一个块级作用域。

if (true) {
    var message = "hello";
    console.log(message); // hello
}
console.log(message); // hello
 
 
if (true) {
    let message = "hello";
    console.log(message); // hello
}
console.log(message); // error: message is not defined
 
2.重复声明同名变量,重新赋值
      let a = 666;
      console.log(a); //666
      if (true) {
        let a = 888;
        console.log(a); //888
      }
      console.log(a); //666
      let a = 666;
      console.log(a); //666
      if (true) {
        a = 888;
        console.log(a); //888
      }
      console.log(a); //888
//var 关键字可以声明同名变量,实际第二次声明是对第一次声明的变量重新赋值
var num1 = 10;
var num1 = 20;
console.log(num1);  // 20
​
//let 和const 关键字不能重复声明同名变量
let num2 = 10;
let num2 = 20;  // Uncaught SyntaxError: Identifier 'num2' has already been declared 
​
//let 和 var 在声明变量时,可以不用初始化
let num3;  
console.log(num3);  // undefined
var num4;  
console.log(num4);  // undefined
​
//const 声明常量时必须初始化,因为 `const` 关键字声明的是常量,声明后不能再赋值
const num5;  // Uncaught SyntaxError: Missing initializer in const declaration
​
//let 声明的变量可以重新赋值
let num1 = 10;
num1 = 20;
console.log(num1);  // 20
//const 只能在声明时赋值,之后不能再重新赋值
const num2 = 10;
num2 = 20;  // Uncaught TypeError: Assignment to constant variable.
3.变量提升
//用var命名的变量有变量提升
console.log(num1);  // undefined
var num1 = 10;
// 以上代码运行时,相当于下面的写法
​
var num2;  // 声明提升到作用域最顶端
console.log(num2);  // undefined
num = 10;

//用 let 或 const 命名的变量没有变量提升
console.log(num3); // Uncaught ReferenceError: num3 is not defined
let num3 = 10;      
​
console.log(num4); // Uncaught ReferenceError: num4 is not defined
const num4 = 10;
      /* 在函数的内部,用var定义name变量,当i等于false时,按照Java语言,else里是拿不到name的,并且会显示报错
       * 但是却不会报错,这是因为javascript的变量提升机制,它会在代码最上面,定义一个变量:var name;
       */
      function aaa(i) {
        if (i) {
          var name = "wjdsg";
        } else {
          console.log(name); //不会报错,输出undefined
          return null;
        }
      }
      aaa(false);
 
      //在块中,定义变量:a,在块外面,也可以拿到a(var的全局作用域)
      {
        var a = 1;
      }
      console.log(a);
 
      /* 在java中,变量i是随着for循环结束而销毁,i的作用也只能在for循环中,但是在Javascript中,
       * 在for外也可以取到值
       */
      for (var i = 0; i < 10; i++) {}
      console.log(i);
 
      /* 定义两个名字相同的变量也不会报错
       */
      var index = 10;
      var index = 100;
      console.log(index);
 
      /* 解决方法,尽量不要使用:var,
       * 使用块级声明:let和const
       */
 
      /* const:定义常量,一但被定义,一定要赋值,赋值之后,不能被修改
       * 当用const定义对象的时候,即为常量对象,内存空间不能够覆盖,
       * 但是却可以添加属性:person.age=12;
       */
      const person = {
        id: 1,
        name: "wjdsg",
      };
 
      person.id = 2;
      person.age = 12;
      console.log(person);
 
      /* 总结,无论是const或者let,都可以解决变量提升的问题
       * 注:for循环不能用const,只能用var或者let
       */

var,let,const关键字声明变量的区别_第1张图片

4.for循环定时器中var和let声明的区别
for (var i = 0; i < 5; i++) {
    setTimeout( () => {
        console.log(i); // 5、5、5、5、5
    }, 0 )
}
 
for (let i = 0; i < 5; i++) {
    setTimeout( () => {
        console.log(i); // 0、1、2、3、4
    }, 0 )
}
  • var是因为在退出循环时,迭代变量保存的是导致循环退出的值,也就是 5。在之后执行异步操作定时器回调时,所有的i都是同一个变量,因此输出的都是同一个最终值。
  • 而在使用let声明迭代变量时,JS 引擎在后台会为每个迭代循环声明一个新的迭代变量,每个 setTimeout 引用的都是不同的变量实例,所以 console.log 输出的是循环执行过程中每个迭代变量的值。
5.总结
  • var 声明的范围是全局作用域,let 和 const 声明的范围是块作用域
  • var 声明的变量会被提升到函数作用域的顶部,let 和 const 声明的变量不存在提升
  • var 允许在同一个作用域中重复声明同一个变量,let 和 const 不允许
  • const 的行为与 let 基本相同,唯一的区别是,使用 const 声明的变量必须进行初始化,且不能被重新赋值

var,let,const关键字声明变量的区别_第2张图片

你可能感兴趣的:(JavaScript,前端,javascript,开发语言,html5,css3,前端框架,es6)