资讯专栏INFORMATION COLUMN

总结下var、let 和 const 的区别

pingink / 3403人阅读

摘要:前言和的区别是老生常谈,看到网上一些文章的总结,有的不太全面,甚至有的描述不太准确,在这里尽量全面的总结下这三者的区别。最后以上大概是总结后的内容,看来,还是多用吧。

前言

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

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

1. let 使用块级作用域

在 ES6之前,ES5中js只有全局作用域和函数作用域,例如:

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 声明的变量,在块外是不可见的,如果引用的话就会报错。

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

在 js 中变量和函数都会提升:

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

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

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...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/108530.html

相关文章

  • varlet/const区别

    showImg(https://segmentfault.com/img/remote/1460000017757580); let和const是 ES6 新增的命令,用于声明变量,这两个命令跟 ES5 的var有许多不同,并且let和const也有一些细微的不同,再认真阅读了阮一峰老师的文档后,发现还是有一些不知道的细节... 博客、前端积累文档、公众号、GitHub 内容: var和let...

    SHERlocked93 评论0 收藏0
  • 箭头函数letconst声明小总结

    摘要:无关紧要的开头最近因为一些事儿辞了刚刚找到的工作,处在待业状态,去稍微的面了几家公司,有大有小,有好有坏,发现大家问起来的一些的问题跟我想的不一样,下来再去研究发现我说的还是有些缺陷,虽然意思是对的,但是表达的很奇怪,怪不得面试官会误会,参 /*===无关紧要的开头start===*/最近因为一些事儿辞了刚刚找到的工作,处在待业状态,去稍微的面了几家公司,有大有小,有好有坏,发现大家问...

    2i18ns 评论0 收藏0
  • var let const 区别

    摘要:区别标签空格分隔规范新增了两种变量声明方式,虽然在项目中也经常用到和但是和到底有什么区别,今天做下总结。不允许重复声明不允许在相同作用域内,重复声明同一个变量。 var let const 区别 标签(空格分隔): ES6 ES6规范新增了let、const两种变量声明方式,虽然在项目中也经常用到let和const但是和var到底有什么区别,今天做下总结。 1、let 声明的变量只在...

    Ververica 评论0 收藏0
  • Javascript基础之-varletconst深入解析(二)

    摘要:规范对其是这样进行的描述的。声明定义了在正在运行的执行上下文作用域内的变量环境中的变量。在执行时,由带有的定义的变量被赋其设定项的的值。由于变量已经被声明,是可访问的,因此会打印出正确的结果。 你想在在变量声明之前就使用变量?以后再也别这样做了。 新的声明方式(let,const)较之之前的声明方式(var),还有一个区别,就是新的方式不允许在变量声明之前就使用该变量,但是var是可以...

    XiNGRZ 评论0 收藏0
  • ES6精解:letconst、块级作用域

    摘要:命令新增了命令,跟类似,都是用来声明变量的不允许重复声明报错不存在变量提升报错正确写法为既要先定义,后面才能有这个值,否则会报错,如果改成会提示未定义,但是就直接报错了暂时性死区只要在块级作用域里面存在则它所声明的变量就绑定在这个块级作用域 let命令 ES6新增了let命令,跟var类似,都是用来声明变量的 1.不允许重复声明 { let a = 1; let a =...

    BWrong 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<