在 ES6 出现之前,必须使用 var
声明。 但是,前端开发出现的一些问题与使用 var
声明的变量有关。 这就是为什么必须要有新的方法来声明变量。 首先,让我们在讨论这些问题之前更多地了解 var
。
作用域本质上是指变量/函数可供访问的范围。 var
可以在全局范围声明或函数/局部范围内声明。
当在最外层函数的外部声明var
变量时,作用域是全局的。 这意味着在最外层函数的外部用var
声明的任何变量都可以在windows
中使用。
当在函数中声明var
时,作用域是局部的。 这意味着它只能在函数内访问。
要进一步了解,请查看下面的示例。
var greeter = 'hey hi'; function newFunction() { var hello = 'hello'; }
这里,greeter
是全局范围的,因为它存在于函数外部,而hello
是函数范围的。 因此,我们无法在函数外部访问变量hello
。 因此,如果我们这样做:
var tester = 'hey hi'; function newFunction() { var hello = 'hello'; } console.log(hello); // error: hello is not defined
我们会收到错误消息,这是由于函数外部没有hello
导致的。
这意味着我们可以在相同的作用域内执行下面的操作,并且不会出错
var greeter = 'hey hi'; var greeter = 'say Hello instead';
又比如
var greeter = 'hey hi'; greeter = 'say Hello instead';
变量提升是 JavaScript 的一种机制:在执行代码之前,变量和函数声明会移至其作用域的顶部。 这意味着如果我们这样做:
console.log(greeter); var greeter = 'say hello';
生面的代码会被解释为:
var greeter; console.log(greeter); // greeter is undefined greeter = 'say hello';
因此,将var
声明的变量会被提升到其作用域的顶部,并使用 undefined 值对其进行初始化.
var
有一个弱点。 我将使用以下示例进行说明:
var greeter = "hey hi"; var times = 4; if (times > 3) { var greeter = "say Hello instead"; } console.log(greeter) // "say Hello instead"
由于times> 3
返回 true,因此将greeter
重新定义为saysay Hello
。 如果你有是故意重新定义greeter
,这段代码是问题的,但是当你不知道之前已经定义了变量greeter
时,这将成为产生问题。
如果在代码的其他部分使用了greeter
,这可能会导致代码中出现许多错误。 这就是为什么需要let
和const
的原因。
let
现在已经成为变量声明的首选。 这并不奇怪,因为它是对var
声明的改进。 它也解决了我们刚刚介绍的var
问题。 让我们考虑一下为什么会这样。
块是由 {} 界定的代码块,大括号中有一个块.大括号内的任何内容都包含在一个块级作用域中.
因此,在带有let
的块中声明的变量仅可在该块中使用。 让我用一个例子解释一下
let greeting = 'say Hi'; let times = 4; if (times > 3) { let hello = 'say Hello instead'; console.log(hello); // "say Hello instead" } console.log(hello); // hello is not defined
我们看到在其代码块(定义它的花括号)之外使用hello
会返回错误。 这是因为let
变量是块范围的.
就像var
一样,用let
声明的变量可以在其范围内被修改。 但与var
不同的是,let
变量无法在其作用域内被重新声明。 来看下面的栗子:
let greeting = 'say Hi'; greeting = 'say Hello instead';
上面的代码将会返回一个错误:
let greeting = 'say Hi'; let greeting = 'say Hello instead'; // error: Identifier 'greeting' has already been declared
但是,如果在不同的作用域中定义了相同的变量,则不会有错误:
let greeting = 'say Hi'; if (true) { let greeting = 'say Hello instead'; console.log(greeting); // "say Hello instead" } console.log(greeting); // "say Hi"
为什么没有错误? 这是因为两个实例的作用域不同,因此它们会被视为不同的变量。
这个事实说明:使用let
,是比var
更好的选择。 当使用let
时,你不必费心思考