Javascript 中 var 和 let 、const 的区别及使用方法

作者:zz_sa 时间:2024-05-09 15:07:41 

1.var、let、const简介

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

var 声明

         var 关键字在定义变量中定义和使用中不严格。

1.定义单个变量和同时定义多个变量,在定义多个变量时用逗号隔开。两者不赋值操作。

<script>
   var userName;
   var age,address,phone;
   console.log(userName)
   console.log(age)
   console.log(address)
   console.log(phone)
</script>

        显然这样输出的值为 undefined 类型。 

Javascript 中 var 和 let 、const 的区别及使用方法

 2.定义单个变量和同时定义多个变量,在定义多个变量时用逗号隔开。两者赋值操作。

<script>
   var userName = 'sa'
   var age = 18,address = '南昌',phone = '19238824523'
   console.log(userName)
   console.log(age)
   console.log(address)
   console.log(phone)
</script>

Javascript 中 var 和 let 、const 的区别及使用方法

 3.var重复声明变量和赋值

        在 ECMAScript 中 var 关键字声明的变量可以重复声明,但是赋值操作会覆盖前面已经给变量赋的值。值不仅可以改变数据也可以改变相关的数据类型。

<script>
var userName = 'sa'
console.log(userName)
var userName = 77  // 这边也可以省略var
console.log(userName)
</script>

Javascript 中 var 和 let 、const 的区别及使用方法

4.var 声明的作用域问题

        var声明的全局变量全局作用域会挂载到 window 对象上,可以使用window. 的形式访问该变量,或者直接使用变量名的方式。在函数体内部的用var声明的变量是局部变量,当省略 va r时,当前变量会定义为全局变量,但是当我要得到这个变量的值时,我们需要先执行一下函数。

<script>
   // 定义函数,测试两个变量是否在函数体外部可以使用
   function test(){
       var msg = '这是局部变量'
       message = '这是全局变量'

}
   test()
   console.log(window.message)
   console.log(message)
   console.log(msg)
</script>

        输出结果如下:message 可以获得,但是 msg 不行。关键问题在于,使用 var 声明的变量会成为包含它在函数的局部变量。在一个函数内部定义了一个变量,就意味着该变量将在函数退出时被销毁。

Javascript 中 var 和 let 、const 的区别及使用方法

 5.var 声明提升

        &ldquo;提升&rdquo;,也就是把所有的变量声明都拉到函数作用域的顶部。此外,反复多次使用 var 声明同一个变量也没有问题。

<script>
   // 定义函数,测试变量提升
   function test(){
       console.log(msg)
       var msg = '变量'
       console.log(msg)
   }
   test()
</script>

        正常的我们会认为,变量未定义先使用,会报一个 ~~ is not defined 的错误。但是 var 存在变量提升的行为,以上代码等同于:

function test(){
       var msg
       console.log(msg)
        msg = '变量'
       console.log(msg)
   }
   test()

两者的输出结果都是如下:

Javascript 中 var 和 let 、const 的区别及使用方法

let 声明

        let和var的作用差不多,但是有着非常重要的区别。最明显的区别就是,let 声明的范围是块作用域,而 var 声明的范围是函数作用域。

        代码块由一个左花括号( { )和一个右花括号( } )标识结束。

1.简单示意 let 和 var 的区别

// let 和 var 的作用域区别
if (true) {
   var username = 'sa'
   let msg = 'ss'
}
   console.log(username)
   console.log(msg)

        在当前代码中,let 定义的 msg 只作用与 if 的代码块中,在外部无法使用 msg 该变量。

Javascript 中 var 和 let 、const 的区别及使用方法

 2. let 不可以重复声明变量,var 可以重复声明变量

<script>
var userName
var userName
let msg
let msg
</script>

        这里提示 msg 重复定义:

Javascript 中 var 和 let 、const 的区别及使用方法

3.将 let 和 var 混合重复定义一个变量

<script>
var userName
let userName

let msg
var msg
// 这边将会报一个重复定义的错误

</script>

Javascript 中 var 和 let 、const 的区别及使用方法

 当然,JavaScript 引擎会记录用于变量声明的标识符及其所在的块作用域,因此嵌套使用相同的标识符不会报错,因为同一个块中没有重复声明。

<script>
let age = 20
console.log(age) // 20
if (true) {
   let age = 18
   console.log(age) // 18
}
</script>

4.let 声明的变量不会在作用域中被提升

<script>
function test() {
   console.log(age)
   let age = 20
}
test()
</script>

Javascript 中 var 和 let 、const 的区别及使用方法

         let 声明的变量不会在作用域中被提升是和 var 一个很重要的区别。所以 let 声明变量,必须要先声明后使用,否则报错。 

        在解析代码时,JavaScript 引擎也会注意在块后面的 let 声明,只不过在此之前不能以任何方式来引用未声明的变量。在 let 声明之前的执行瞬间被称为&ldquo;暂时性死区&rdquo;,在此阶段引用任何后面才声明的变量都会抛出 ReferenceError。

5.let的全局声明不会成为 window 对象的属性( var 声明的变量则会)

<script>
var msg = '我是var声明的变量'
let mess = '我是let声明的变量'
console.log(window.msg)
console.log(window.mess)
</script>

Javascript 中 var 和 let 、const 的区别及使用方法

 6.条件声明

        在使用 var 声明变量时,由于声明会被提升,JavaScript 引擎会自动将多余的声明在作用域顶部合并为一个声明。因为 let 的作用域是块,所有不可能检查是否已经使用了 let 声明过同名变量,同时也就不可能在没有声明的情况下使用它。

错误示范如下:

<script>
   // 当前声明两个变量
   var msg = '我是var声明的变量'
   let mess = '我是let声明的变量'
</script>
<script>
   var msg = 'sa' // 这里没问题,var 存在变量提升声明来处理
   let mess = 'ss' // 当之前声明了变量mess,这里将报错,let 不存在变量提升
</script>

Javascript 中 var 和 let 、const 的区别及使用方法

<script>
let mess // 当前只声明了一个 let 变量
</script>
<script>
 if (typeof mess === 'undefined'){
     let mess
 }
 mess = 'sa' // mess 被限制在 if {} 作用域块中,当前赋值为全局赋值
 console.log(mess) // sa
 try {
     console.log(age)
 }
 catch (error) {
     let age
 }
 age = 20  // age 被限制在 catch {} 作用域块中,当前赋值为全局赋值
 console.log(age) // 20
</script>

Javascript 中 var 和 let 、const 的区别及使用方法

 注:条件声明比较难以理解,这是一种反模式。这会让我们的程序变得更加难理解。

7.for循环中的 let 声明

        当我们在用 var 时,for循环定义的迭代变量会渗透到循环体外部。

for (var i = 0; i < 6; i++) {
   setTimeout(() => {
       console.log(i) },0) //  这将打印六个 6
}

Javascript 中 var 和 let 、const 的区别及使用方法

        这种原因的出现情况是因为由于 var 声明的变量不存在块级作用域在退出循环时,迭代变量保存的是导致循环退出的值:6。在之后执行超时逻辑时,所有的 i 都是同一个变量,最终导致输出的值相同。

        使用 let 声明 i 时:

for (let i = 0; i < 6; i++) {
   setTimeout(() => {
       console.log(i) },0) //  这将打印六个 6
}

Javascript 中 var 和 let 、const 的区别及使用方法

        当使用let 声明变量时,JavaScript 引擎在后台会为每一个迭代循环声明一个新的迭代变量,每个 setTimeout 引用的都是不同的变量实例,所以输出的值不同也就是我们期望中的值,也是循环执行过程中每一个迭代变量的值。

        在我们对dom节点使用for循环绑定事件时,一般也是用 let 声明迭代变量。

const 声明

         const 的行为和 let 基本相同,唯一一个重要的区别就是它在声明变量的同时必须初始化变量,且尝试修改 const 声明的变量会导致运行时错误。

1.const 声明的变量不允许修改

<script>
const age = 20
age = 30
</script>

Javascript 中 var 和 let 、const 的区别及使用方法

 2.const 也是不可重复声明

<script>
const age = 20
const age = 30
</script>

Javascript 中 var 和 let 、const 的区别及使用方法

 3.const 声明的作用域也是块

<script>
if (true) {
   const age = 30
}
console.log(age)
</script>

Javascript 中 var 和 let 、const 的区别及使用方法

4.const 中注意的点

         const 声明限制只适用于它指向变量的引用。换句话说,如果 const 变量引用的是一个对象,那么修改这个对象内部的值不违反 const 的限制。引用未发生改变就行。

例如:修改了对象中 name 的值但不会报错。

const student = {
   name: 'sa',
   age: 18,
   address: 'shanghai'
}
student.name = 'saa'
console.log(student.name) // 输出saa

        如果你想用const 声明一个不会被修改的 for 循环变量,那也是可以的。也就是说,每次迭代只是创建一个新变量。这对 for-in 和 for-of 循环都是有意义的。

例如:

for (const key in { a: 1, b: 2, c: 3 }){
   console.log(key)
}

Javascript 中 var 和 let 、const 的区别及使用方法

 总结

在我们日常使用变量声明时,遵循一下几点:

        1.不使用 var

        2.const 优先,let 次之

来源:https://blog.csdn.net/weixin_55852686/article/details/128405162

标签:js,var,let,const
0
投稿

猜你喜欢

  • Django多进程滚动日志问题解决方案

    2023-02-01 16:21:16
  • 浏览器常用基本操作之python3+selenium4自动化测试(基础篇3)

    2023-10-19 04:49:03
  • python/golang实现循环链表的示例代码

    2021-10-31 23:32:20
  • Python中的流程控制详解

    2023-07-22 20:31:54
  • sql 语句中的 NULL值

    2024-01-14 06:41:16
  • javascript封装的下拉导航菜单渐显效果

    2007-08-04 20:11:00
  • 在Python中预先初始化列表内容和长度的实现

    2022-03-17 04:30:37
  • 一个无组件上传的ASP代码

    2007-10-09 19:49:00
  • python导入导出redis数据的实现

    2023-02-24 11:10:55
  • 合理设置内存让数据库与其他程序共存

    2009-05-21 16:24:00
  • Python Pillow Image Invert

    2023-10-02 12:33:30
  • 模拟实现 Range 的 insertNode() 方法

    2010-11-30 21:39:00
  • asp 正则实现清除html文本格式的函数代码

    2011-03-09 11:21:00
  • Python如何用NumPy读取和保存点云数据

    2022-05-26 17:41:19
  • python实现m3u8格式转换为mp4视频格式

    2021-05-09 00:48:02
  • Oracle性能究极优化 上第1/2页

    2010-07-30 13:26:00
  • pytorch通过训练结果的复现设置随机种子

    2021-04-19 07:58:53
  • anaconda安装后打不开解决方式(亲测有效)

    2023-01-21 09:40:15
  • Django使用httpresponse返回用户头像实例代码

    2021-08-28 04:47:03
  • 用css3-tranistions实现平滑过渡

    2009-12-23 19:24:00
  • asp之家 网络编程 m.aspxhome.com