JavaScript Let

86 阅读2分钟

ECMAScript 2015

ES2015 引入了两个重要的 JavaScript 新关键词:letconst

这两个关键字在 JavaScript 中提供了块作用域(Block Scope)变量(和常量)。

在 ES2015 之前,JavaScript 只有两种类型的作用域:全局作用域函数作用域

全局作用域

全局(在函数之外)声明的变量拥有全局作用域

<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>

<script>
var carName = "porsche";
myFunction();

function myFunction() {
    document.getElementById("demo").innerHTML =
    "I can display " + carName;
}
</script>

</body>
</html>

函数作用域

局部(函数内)声明的变量拥有函数作用域

<!DOCTYPE html>
<html>
<body>
<p id="demo1"></p>
<p id="demo2"></p>

<script>
myFunction();

function myFunction() {
    var carName = "porsche";
    document.getElementById("demo1").innerHTML =
    typeof carName + " " + carName;
}

document.getElementById("demo2").innerHTML =
typeof carName;
</script>

</body>
</html>

JavaScript 块作用域

通过 var 关键词声明的变量没有块作用域

在块 **{} **内声明的变量可以从块之外进行访问。

重新声明变量

使用 var 关键字重新声明变量会带来问题。

在块中重新声明变量也将重新声明块外的变量:

<p id="demo"></p>

<script>
var  x = 10;
// Here x is 10
{  
  var x = 2;
  // Here x is 2
}
// Here x is 2
document.getElementById("demo").innerHTML = x;
</script>

使用 let 关键字重新声明变量可以解决这个问题。

循环作用域

let和var

<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>
<p id="da"></p>
<script>
var i = 1;
for (var i = 0; i < 10; i++) {
  // 一些语句
}
document.getElementById("demo").innerHTML = i;


let a = 3;
for (let a = 0; a < 10; a++) {
  // 一些语句
}
document.getElementById("da").innerHTML = a;
//循环中用var定义执行完毕,用let定义只执行值得次数
</script>

</body>
</html>

在循环中使用的变量使用 var 重新声明了循环之外的变量

在循环中使用的变量使用 let 并没有重新声明循环外的变量。

如果在循环中用 let 声明了变量 i,那么只有在循环内,变量 i 才是可见的。

循环中用var定义执行完毕,用let定义只执行值的次数

如果在函数内不使用var,该变量是全局的


在函数中使用var声明变量的时候,该变量是局部的

HTML 中的全局变量

使用 JavaScript 的情况下,全局作用域是 JavaScript 环境。

在 HTML 中,全局作用域是 window 对象。

通过 var 关键词定义的全局变量属于 window 对象:

通过 let 关键词定义的全局变量不属于 window 对象:

重新声明

允许在程序的任何位置使用 var 重新声明 JavaScript 变量:(就近原则)

在相同的作用域,或在相同的块中,通过 let 重新声明一个 var 变量是不允许的:( let只执行第一个其他的不会执行 )

var 声明的变量会提升到顶端,var可以在声明变量之前就使用它

通过 let 定义的变量不会被提升到顶端。

在声明 let 变量之前就使用它会导致 ReferenceError。

变量从块的开头一直处于“暂时死区”,直到声明为止: