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 类型。
2.定义单个变量和同时定义多个变量,在定义多个变量时用逗号隔开。两者赋值操作。
<script>
var userName = 'sa'
var age = 18,address = '南昌',phone = '19238824523'
console.log(userName)
console.log(age)
console.log(address)
console.log(phone)
</script>
3.var重复声明变量和赋值
在 ECMAScript 中 var 关键字声明的变量可以重复声明,但是赋值操作会覆盖前面已经给变量赋的值。值不仅可以改变数据也可以改变相关的数据类型。
<script>
var userName = 'sa'
console.log(userName)
var userName = 77 // 这边也可以省略var
console.log(userName)
</script>
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 声明的变量会成为包含它在函数的局部变量。在一个函数内部定义了一个变量,就意味着该变量将在函数退出时被销毁。
5.var 声明提升
“提升”,也就是把所有的变量声明都拉到函数作用域的顶部。此外,反复多次使用 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()
两者的输出结果都是如下:
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 该变量。
2. let 不可以重复声明变量,var 可以重复声明变量
<script>
var userName
var userName
let msg
let msg
</script>
这里提示 msg 重复定义:
3.将 let 和 var 混合重复定义一个变量
<script>
var userName
let userName
let msg
var msg
// 这边将会报一个重复定义的错误
</script>
当然,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>
let 声明的变量不会在作用域中被提升是和 var 一个很重要的区别。所以 let 声明变量,必须要先声明后使用,否则报错。
在解析代码时,JavaScript 引擎也会注意在块后面的 let 声明,只不过在此之前不能以任何方式来引用未声明的变量。在 let 声明之前的执行瞬间被称为“暂时性死区”,在此阶段引用任何后面才声明的变量都会抛出 ReferenceError。
5.let的全局声明不会成为 window 对象的属性( var 声明的变量则会)
<script>
var msg = '我是var声明的变量'
let mess = '我是let声明的变量'
console.log(window.msg)
console.log(window.mess)
</script>
6.条件声明
在使用 var 声明变量时,由于声明会被提升,JavaScript 引擎会自动将多余的声明在作用域顶部合并为一个声明。因为 let 的作用域是块,所有不可能检查是否已经使用了 let 声明过同名变量,同时也就不可能在没有声明的情况下使用它。
错误示范如下:
<script>
// 当前声明两个变量
var msg = '我是var声明的变量'
let mess = '我是let声明的变量'
</script>
<script>
var msg = 'sa' // 这里没问题,var 存在变量提升声明来处理
let mess = 'ss' // 当之前声明了变量mess,这里将报错,let 不存在变量提升
</script>
<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>
注:条件声明比较难以理解,这是一种反模式。这会让我们的程序变得更加难理解。
7.for循环中的 let 声明
当我们在用 var 时,for循环定义的迭代变量会渗透到循环体外部。
for (var i = 0; i < 6; i++) {
setTimeout(() => {
console.log(i) },0) // 这将打印六个 6
}
这种原因的出现情况是因为由于 var 声明的变量不存在块级作用域在退出循环时,迭代变量保存的是导致循环退出的值:6。在之后执行超时逻辑时,所有的 i 都是同一个变量,最终导致输出的值相同。
使用 let 声明 i 时:
for (let i = 0; i < 6; i++) {
setTimeout(() => {
console.log(i) },0) // 这将打印六个 6
}
当使用let 声明变量时,JavaScript 引擎在后台会为每一个迭代循环声明一个新的迭代变量,每个 setTimeout 引用的都是不同的变量实例,所以输出的值不同也就是我们期望中的值,也是循环执行过程中每一个迭代变量的值。
在我们对dom节点使用for循环绑定事件时,一般也是用 let 声明迭代变量。
const 声明
const 的行为和 let 基本相同,唯一一个重要的区别就是它在声明变量的同时必须初始化变量,且尝试修改 const 声明的变量会导致运行时错误。
1.const 声明的变量不允许修改
<script>
const age = 20
age = 30
</script>
2.const 也是不可重复声明
<script>
const age = 20
const age = 30
</script>
3.const 声明的作用域也是块
<script>
if (true) {
const age = 30
}
console.log(age)
</script>
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)
}
总结
在我们日常使用变量声明时,遵循一下几点:
1.不使用 var
2.const 优先,let 次之
到此这篇关于Javascript 中 var 和 let 、const 的区别以及具体使用效果的文章就介绍到这了,更多相关js中var和 let 、const 区别内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!