2015 年 ES6 发布,它改变了我们在 javascript 中声明和使用变量的方式。ES2015(ES6)引入了新的变量声明方法,let和const。
这两种方法解决了开发人员在使用 var 时面临的问题,let 和 const 有自己的属性让我们深入探讨。
变量
var 是关键字,用于变量声明。使用 var 我们可以声明具有全局范围的变量,它提供程序中相同变量的提升和重新声明。
变量范围
var 语句声明一个函数范围或全局范围的变量,可选择将其初始化为一个值。
用var声明的变量的范围是其当前执行上下文,它是封闭函数和在其中声明的函数具有函数范围,或者在任何函数外部声明的变量具有全局范围。
使用var的重复变量声明不会触发错误,即使在严格模式下也是如此,除非执行另一次赋值,否则变量不会丢失其值。
函数作用域和全局作用域
var userName = "Mario"// globle scopeconsole.log(userName); // output: MariofunctionAuth(){
var password = "xyz"; // fuction scopeconsole.log(password); //output: xyz
}
Auth();
这里的 userName 变量有一个全局范围,可以在程序的任何地方使用,但是 password 有一个函数范围,它只能在 Auth() 函数内部使用。
我们尝试在 Auth 函数之外访问密码变量,它给出 ReferenceError 说 userName 未定义。
var userName = "Mario"// globle scopeconsole.log(userName); // output: MariofunctionAuth(){
var password = "xyz"; // fuction scopeconsole.log(password); //output: xyz
}
Auth();console.log(password) // gives ReferenceError: userName is not defined
变量提升
JavaScript提升是指解释器似乎在执行代码之前将函数、变量或类的声明移动到其作用域顶部的过程。
因为var声明是在执行任何代码之前处理的,所以在代码中的任何地方声明一个变量等同于在顶部声明它。
这也意味着一个变量可以在它被声明之前看起来是被使用过的。这种行为称为提升,因为看起来变量声明已移至函数或全局代码的顶部。
例如,我们可以在使用 var 声明之前分配 userName 的值。
userName = "Mario"var userName;
重要的是要指出只有变量的声明被提升,而不是它的初始化。初始化仅在到达赋值语句时发生。在此之前,变量保持未定义状态。
console.log(userName); // output: undefined
userName = "mario"var userName;
使用 var 重新声明同一个变量
我们可以重新声明已经在程序中声明的同一个变量,因为我们声明一个变量,该变量的值与旧变量相同,直到我们为其分配新值。
var userName = "Mario";
var userName;console.log(userName); //output: Mario
var 的问题
在 Javascript 中,使用关键字“var”多少次并不重要。如果它在同一个函数中具有相同的名称,则您指向同一个变量。
让我们看一个例子
var userName = "Mario";
var password = "xyz";if(password === "xyz"){
userName = "Will smith";
}console.log(userName); // output: will smith
如我们所见,我们只想更改 if 块中的用户名,但值也在全局范围内更改。
这个问题可以通过let和count来解决,我们可以更好地控制范围内的值。
let
let 关键字解决了我们面对 var 的问题,它为变量提供了块作用域,这意味着变量生命属于块,我们无法在块外访问它。
let userName = "Mario";if(userName){
let password = 1234;
console.log(password); // output: 1234
}console.log(password); // gives ReferenceError
let 可以更新但不能重新声明
与 var 不同,我们不能在同一范围内用 let 重新声明同一个变量。但是我们可以更新用 let 声明的变量的值。
let userName = "Mario";
userName = "Will"; // posiblelet userName = "Will"// error
但是如果同一个变量定义在不同的作用域中,则不会报错
let userName = "Mario";
let password = 1234;console.log(userName); // output: Marioif(password===1234){
let userName = "will";
console.log(userName); //output: will;
}console.log(userName); //output:Mario
let的调用
就像var 一样,让声明被提升到顶部。与初始化为undefined的var不同,let关键字未初始化。因此,如果您尝试在声明之前使用let变量,则会出现引用错误。
console.log(userName); // ReferenceError: Cannot access 'userName' before initializationlet userName = "Mario";
常数
用const声明的变量保持常量值。const声明与let声明有一些相似之处。
const 声明是块作用域的
与let声明一样,const声明只能在声明它们的块内访问。
当我们使用 const 声明时,我们必须在声明时初始化变量,否则它会给出 SyntaxError: Missing initializer in const declaration。
const 不能被更新或重新声明
这意味着用const声明的变量的值在其范围内保持不变。它不能更新或重新声明。所以如果我们用const声明一个变量。
const userName= "Mario";
userName = "will";// error: Assignment to constant variable. const password = 1234;
const password // error: Identifier 'password' has already been declared
对于使用const声明的对象,此行为在某种程度上有所不同。虽然无法更新const对象,但可以更新对象的属性。
这是可能的,因为变量存储的是对象的地址而不是数据,所以地址将是我们无法更改的常量,但可以更新对象引用的属性。
const user = {
userName: "Mario",
password: 1234
}console.log(user.userName); // output: Mario
user.userName = "will"console.log(user.userName); // output: will
const 的提升
就像let一样,cont声明被提升到顶部但没有被初始化。
下表简单介绍了javascript中let和var、const的区别:
var | let | const |
var 具有函数或全局范围。 | 让我们有块范围。 | const 变量具有块作用域。 |
它被提升到其范围的顶部并初始化为未定义。 | 它还被提升到其范围的顶部,但没有初始化。 | 它还被提升到其范围的顶部,但没有初始化。 |
它可以更新或重新声明。 | 只能更新,不能重新声明。 | 它不能更新或重新声明。 |