0


搞懂JavaScript中var和let、const的区别与使用

在ES5中我们声明变量都是使用var关键字,在ES6开始新增了两个关键字let和const。var可以算作是js早期的一个设计缺陷,所以不妨先学习更为先进的用法,再区分它们之前的区别,搞清楚let和const解决了var声明变量的什么痛点。


1.let/const的基本使用

let关键字:

  • 在基本功能上,let和var一样都是声明一个变量,但是存在许多细节上的差异,后面会介绍到。
    var message = "message"
      message = "var可以修改"
      console.log(message)

      let message2 = "message"
      message2 = "let也可以修改"
      console.log(message2)

const关键字:

  • const关键字是constant单词的缩写,表示常量、衡量的意思;
  • 它表示保存的数据一旦被赋值,就不能被修改;
  • 但是如果赋值的是引用类型,那么可以通过引用找到对应的对象,修改对象的内容。

使用const定义一个常量,如果尝试去修改这个常量的值的话,会报错

    const message3 = "message3"
      message3 = "尝试去修改message3"
      console.log(message3);

但如果修改的是由const定义的引用类型(例如对象),可以修改对象里面的内容

      const info = {
        name: "zzz",
        age: 18
      }

      info.name = "qqq"
      console.log(info) 

原先的name值的zzz被修改成了qqq

2.let/const不允许重复声明变量

在同一个作用域中,使用var定义变量,允许重复声明;

而用let定义变量,在vscode中就会报错。

如果先用var定义一个变量,再用let定义一样名称的变量呢?

在vscode中没有报错了,但是在浏览器中还是会有报错

let、const同样也不能重复声明对象

3.let/const没有作用域提升

var是会有作用域提升的;

什么是作用域提升呢?

如果我们在使用var声明一个变量之前进行了调用,输出的内容会是undefined,虽然值是undefined,但是是可以访问得到的。

 console.log(message) //undefined
 var message = "message"

但是如果使用let、const声明变量,在声明之前访问就会报错。

在let、const定义的标识符真正执行到声明的代码前是不能被访问的,从块作用域的顶部一直到变量声明完成之前,这个变量处在暂时性死区(TDZ:temporal Dead Zone)

console.log(message)
let message = "message"

是不是使用let、const声明的变量只有在代码执行阶段才会创建?

不是的,这些变量会被创建在包含他们的词法环境被实例化时,是不可以访问它们的,直到词法绑定被求值。

在执行上下文的词法环境创建出来的时候,变量事实上已经被创建了,只是这个变量是不能被访问的。

那么变量已经有了,但是不能被访问,是不是一种作用域的提升呢?

事实上维基百科并没有对作用域提升有严格的概念解释,那么我们自己从字面量上理解;

作用域提升:在声明变量的作用域中,如果这个变量可以在声明之前被访问,那么我们可以称之为作用域提升; 在这里,它虽然被创建出来了,但是不能被访问,我认为不能称之为作用域提升;

所以let、const没有进行作用域提升,但是会在解析阶段被创建出来。

4.let/const不会在window对象添加属性

在全局通过var来声明一个变量,会在window上添加一个属性,但是let/const是不会给window上添加任何属性的。

通过var声明一个变量时:

var message = "message"
var address = "广州市"

在window对象中会保存address的属性。

通过let/const声明变量时:

window中是没有声明的变量的,文档中有说明,var定义的变量和函数会存储在一个object Environment Record里(window对象),而let、const则存储在declarative Environment Record中。

5.let/const有块级作用域

使用var****声明变量时,JavaScript只会形成两个作用域:全局作用域函数作用域。放到一个代码块中定义的变量,外面是可以访问的。

通过let、const、function、class声明的标识符都是具备块级作用域的限制的。

    {
        let foo = "foo"
        function bar() {
          console.log("bar");
        }
        class Person {}
      }
      console.log(foo); //foo is not defined
      bar()
      var p = new Person() //Person is not defined

在代码块中定义的foo和Person类在外面都不能访问到,没有定义,let是有块级作用域的

但浏览器引擎会对函数的声明进行特殊的处理,允许像var那样提升;

6.var/let/const在开发中如何选择

  • 对于var的使用: 我们需要明白一个事实,var所表现出来的特殊性:比如作用域提升、window全局对象、没有块级作用域等都是一些历史遗留问题; 其实是JavaScript在设计之初的一种语言缺陷
  • 当然目前市场上也在利用这种缺陷出一系列的面试题,来考察大家对JavaScript语言本身以及底层的理解;
  • 但是在实际工作中,我们可以使用最新的规范来编写,也就是不再使用var来定义变量了;
  • 对于let、const: 对于let和const来说,是目前开发中推荐使用的;
  • 我们会优先推荐使用const,这样可以保证数据的安全性不会被随意的篡改
  • 只有当我们明确知道一个变量后续会需要被重新赋值时,这个时候再使用let;
  • 这种在很多其他语言里面也都是一种约定俗成的规范,尽量我们也遵守这种规范;

本文转载自: https://blog.csdn.net/m0_51636525/article/details/125166834
版权归原作者 至尊绝伦 所有, 如有侵权,请联系我们删除。

“搞懂JavaScript中var和let、const的区别与使用”的评论:

还没有评论