总结下var、let 和 const 的区别

前言

var 和 let 的区别是老生常谈,看到网上一些文章的总结,有的不太全面,甚至有的描述不太准确,在这里尽可能全面的总结下这三者的区别。es6


let 是 ES6新增的变量类型,用来代替 var 的一些缺陷,跟 var 相比主要有如下区别:浏览器

1. let 使用块级做用域

在 ES6以前,ES5中js只有全局做用域和函数做用域,例如:ide

if(true) {
   var a = 'name'
}
console.log('a',a) // name

做用域是一个独立的地盘,让变量不外泄出去,可是上例中的变量就外泄了出去,因此此时 JS 没有块级做用域的概念。函数

var a = 1;
function fn() {
   var a = 2;
   console.log('fn',a);
}
console.log('global',a);
fn();

全局做用域就是最外层的做用域,若是咱们写了不少行 JS 代码,变量定义都没有用函数包括,那么它们就所有都在全局做用域中。这样的坏处就是很容易冲突。
ES6中加入块级做用域以后:设计

if(true) {
   let a = 'name'
}
console.log('a',a) // Uncaught ReferenceError: a is not defined

块做用域内用 let 声明的变量,在块外是不可见的,若是引用的话就会报错。code

2. let 约束了变量提高而不是没有变量提高

在 js 中变量和函数都会提高:对象

function fn() {
   console.log('a',a);
   var a = 1;  // undefind
}
fn()

a其实已经在调用前被声明了,只是没有被初始化。JavaScript会把做用域里的全部变量和函数提到函数的顶部声明,至关于:ip

function fn() {
   var a;
   console.log('a',a);
   a = 1;  // undefind
}
fn()

JavaScript会使用undefined缺省值建立变量a,事实上浏览器并无把声明语句放到做用域的顶部,在编译阶段,控制流进入域,该域全部的变量和函数的声明先进入内存,文中代码的相对位置不会变更。内存

变量提高指的是变量声明的提高,不会提高变量的初始化和赋值。作用域

而且函数的提高优先级大于变量的提高:

function fn() {
            console.log('a', a);
            var a = 1;
            function a () {
                console.log('I am a function');
            }
        }
        fn() // ƒ a () {console.log('I am a function');}

在上例中, let 声明的变量的做用域以外引用该变量会报错,可是否可理解为 let 没有变量提高?

let a = 'outside';
if(true) {
   console.log(a);//Uncaught ReferenceError: a is not defined
    let a = "inside";
}

报出错误 a 没有被定义,而不是引用了全局做用域里的 a,说明 let 声明的 a 也被提高了。

缘由是 let 设计中的暂时性死区:
当前做用域顶部到该变量声明位置中间的部分,都是该let变量的死区,在死区中,禁止访问该变量。由此,咱们给出结论,let声明的变量存在变量提高, 可是因为死区咱们没法在声明前访问这个变量。

3. let 禁止重复声明变量

使用 var 能够重复声明变量,可是 let 不容许在同一块做用域内重复声明同一个变量:

function fn (){
   var a = 1;
   let a = 2;
   console.log(a); //SyntaxError
}

function fn (){
   let a = 1;
   let a = 2;
   console.log(a); //SyntaxError
}

function fn (a){
   let a = 2;
   console.log(a); //SyntaxError
}

上述代码会报语法错误;

4. let不会成为全局对象的属性

咱们在全局范围内声明一个变量时,这个变量自动成为全局对象的属性(在浏览器和Node.js环境下,这个全局对象分别是windowglobal),但let是独立存在的变量,不会成为全局对象的属性:

var a = 1;
console.log(window.a); //1

let b = 2;
console.log(window.b); // undefined

5. const 声明的常量

以上 let 的规则一样适用于 const,可是跟 let 的区别是 const 声明的变量不能从新赋值,因此 const 声明的变量必须通过初始化

const a = 1;

a = 2; // // Uncaught TypeError: Assignment to constant variable
const b; // Uncaught SyntaxError: Missing initializer in const declaration

最后

以上大概是总结后的内容,看来,仍是多用 let 、const 吧。

参考资料: http://es6.ruanyifeng.com/#do...
相关文章
相关标签/搜索