本文深入解析JavaScript中var、let和const三种变量声明方式的核心差异。重点阐述var的全局或函数级作用域与变量提升特性,对比let和const的块级作用域、暂时性死区及不可重复声明规则。同时说明const在定义对象引用时的可变性与常量本质,帮助开发者根据场景选择正确的声明方式以避免潜在错误。
JavaScript变量声明方式概述
使用var关键字声明的变量,其作用域被限制在声明位置所在的上下文环境中。
var x = 0; // x是全局变量,并且赋值为0。
console.log(typeof z); // undefined,因为z还不存在。
function a() { // 当a被调用时,
var y = 2; // y被声明成函数a作用域的变量,然后赋值成2。
console.log(x, y); // 0 2
function b() { // 当b被调用时,
x = 3; // 全局变量x被赋值为3,不生成全局变量。
y = 4; // 已存在的外部函数的y变量被赋值为4,不生成新的全局变量。
z = 5; // 创建新的全局变量z,并且给z赋值为5。
} // (在严格模式下(strict mode)抛出ReferenceError)
b(); // 调用b时创建了全局变量z。
console.log(x, y, z); // 3 4 5
}
a(); // 调用a时同时调用了b。
console.log(x, z); // 3 5
console.log(typeof y); // undefined,因为y是a函数的本地(local)变量。var与let的作用域差异
通过let声明的变量仅在其声明所在的代码块或子块内有效;相比之下,var声明的变量作用域覆盖整个封闭函数。
function varTest() {
var x = 1;
if (true) {
var x = 2; // 同样的变量!
console.log(x); // 2
}
console.log(x); // 2
}
function letTest() {
let x = 1;
if (true) {
let x = 2; // 不同的变量
console.log(x); // 2
}
console.log(x); // 1
}在ECMAScript 2015标准中,let绑定的变量不再受变量提升机制的约束,这意味着let声明不会像var那样被提升到当前执行上下文的顶部。如果在块中变量初始化之前尝试引用该变量,将会触发ReferenceError错误(而使用var声明变量时,该变量的值表现为undefined)。当在代码块中使用let时,变量的作用域被严格限制在该块内部。需要注意的是,var的作用域范围涵盖其被声明的函数内的区域。
var a = 1;
var b = 2;
if (a === 1) {
var a = 11; // the scope is global
let b = 22; // the scope is inside the if-block
console.log(a); // 11
console.log(b); // 22
}
console.log(a); // 11
console.log(b); // 2const常量的定义与特性
使用const声明常量时,必须在声明的同时为其指定初始值。
const声明创建一个值的只读引用,但这并不意味着该值本身是不可变的(例如,如果引用的内容是对象,其属性仍可修改),它仅表示变量标识符不能被重新分配。此外,常量不能与其所在作用域内的其他变量或函数拥有相同的名称。
// 注意: 常量在声明的时候可以使用大小写,但通常情况下全部用大写字母。
// 定义常量MY_FAV并赋值7
const MY_FAV = 7;
// 报错
MY_FAV = 20;
// 输出 7
console.log("my favorite number is: " + MY_FAV);
// 尝试重新声明会报错
const MY_FAV = 20;
// MY_FAV 保留给上面的常量,这个操作会失败
var MY_FAV = 20;
// 也会报错
let MY_FAV = 20;
// 注意块范围的性质很重要
if (MY_FAV === 7) {
// 没问题,并且创建了一个块作用域变量 MY_FAV
// (works equally well with let to declare a block scoped non const variable)
let MY_FAV = 20;
// MY_FAV 现在为 20
console.log('my favorite number is ' + MY_FAV);
// 这被提升到全局上下文并引发错误
var MY_FAV = 20;
}
// MY_FAV 依旧为7
console.log("my favorite number is " + MY_FAV);
// 常量要求一个初始值
const FOO; // SyntaxError: missing = in const declaration
// 常量可以定义成对象
const MY_OBJECT = {"key": "value"};
// 重写对象和上面一样会失败
MY_OBJECT = {"OTHER_KEY": "value"};
// 对象属性并不在保护的范围内,下面这个声明会成功执行
MY_OBJECT.key = "otherValue";
// 也可以用来定义数组
const MY_ARRAY = [];
// It's possible to push items into the array
// 可以向数组填充数据
MY_ARRAY.push('A'); // ["A"]
// 但是,将一个新数组赋给变量会引发错误
MY_ARRAY = ['B']三种声明方式的具体表现
接下来介绍JavaScript中声明变量的三种主要方式:var、let和const。
var声明的变量具有全局作用域,换句话说,即使在for循环中声明的变量,跳出该循环后依然可以使用。
for(var i=0;i<=1000;i++){
var sum=0;
sum+=i;
}
alert(sum);在for循环内部声明的sum变量,即使跳出for循环后依然可以使用,不会报错并能正常输出结果。
let用于声明块级变量,即局部变量。
在上面的示例中,如果跳出for循环后再使用sum变量,将会报错。let具有严格的作用域限制,变量仅在当前隶属的代码块内有效,不可重复定义同一变量,且不能在声明之前调用(必须先定义再使用),否则报错。不过,在循环体中可以使用let。
注意:必须在代码开头声明'use strict';后才能使用let声明变量,否则浏览器可能无法显示正确结果。
const用于声明常量,同样具有块级作用域,也可用于声明块级变量。
const PI=3.14;它和let一样,不允许重复定义同一变量。const一旦定义,其值无法被修改。
总结
总结
以上所述是小编给大家介绍的JavaScript变量声明var、let、const及区别浅析,希望对大家有所帮助。如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对本站网站的支持!