JavaScript let 命令

螞蟻小編發表於2018-02-03

關於塊級作用域可以參閱ES2015 塊級作用域一章節。

ES2015新增let命令用來宣告變數,使用方式與var類似,但區別也是巨大的。

一.let命令建立塊級作用域:

使用let宣告的變數只在變數宣告時所在的程式碼塊內有效(函式作用域對於let宣告的變數依然有效)。

[JavaScript] 純文字檢視 複製程式碼執行程式碼
if (true) {
  let address = "青島市南區";
}
console.log(address);

上面的程式碼會報錯,因為變數address只在它宣告時所在的程式碼塊中有效。

[JavaScript] 純文字檢視 複製程式碼執行程式碼
if (true) {
  var address = "青島市南區";
}
console.log(address);

使用var宣告變數,則可以正常輸出。

二.不存在變數提升現象:

使用let宣告的變數不存在提升現象,看一段程式碼例項:

[JavaScript] 純文字檢視 複製程式碼執行程式碼
console.log(webName);
var webName= "螞蟻部落";
console.log(webName);

第一次會輸出undefined,因為在進入執行上下文時,使用var宣告變數會提升,但並沒有賦值。

關於變數宣告提升可以參閱JavaScript 變數和函式宣告前置一章節。

[JavaScript] 純文字檢視 複製程式碼執行程式碼
console.log(url);
let url = "www.softwhy.com";

程式碼會報錯,let宣告變數並沒有提升現象,也就是說使用let宣告的變數必須先宣告再使用,再來看一段程式碼:

[JavaScript] 純文字檢視 複製程式碼執行程式碼
console.log(typeof antzone);

變數antzone並沒有宣告,輸出值是undefined。

[JavaScript] 純文字檢視 複製程式碼執行程式碼
console.log(typeof age);
let age = 4;

上面的程式碼會報錯,因為在let宣告變數之前就使用了變數。

三.temporal dead zone:

塊級作用域內,如果變數使用let宣告,那麼此變數就會被封閉在當前作用域內,不再受外部作用域的影響。

[JavaScript] 純文字檢視 複製程式碼執行程式碼
var url = "www.softwhy.com";
function func() {
  console.log(url);
  let url = 1;
}
func()

程式碼會報錯,因為函式作用域內,使用let宣告瞭變數url,那麼url就會被封閉在當前作用域中,不再受外部作用域的影響。又因為在宣告之前使用變數,所以報錯。再來看一段程式碼例項:

[JavaScript] 純文字檢視 複製程式碼執行程式碼
var url = "www.softwhy.com";
if (true) {
  console.log(url);
  let url;
}

上面的程式碼也會報錯,同樣的道理。

temporal dead zone指的是在一個作用域內,let宣告變數之前的這塊區域;如果在此區域內使用變數會報錯。

四.let不允許在同一作用域重複宣告變數:

不能使用let命令在同一作用域重複宣告變數,程式碼例項:

[JavaScript] 純文字檢視 複製程式碼執行程式碼
let url = "www.softwhy.com";
if (true) {
  let url="softwhy.com";
  console.log(url);
}

在不同的作用域,重複宣告變數是沒問題的。

[JavaScript] 純文字檢視 複製程式碼執行程式碼
if (true) {
  let url = "www.softwhy.com";
  let url="softwhy.com";
  console.log(url);
}

在同一作用域內,使用let重複宣告變數會報錯。

五.函式的宣告注意事項:

在ES5嚴格模式下,函式宣告只能存在於全域性作用域和函式作用,在類似if語句這樣的塊中宣告會報錯。

程式碼例項如下:

[JavaScript] 純文字檢視 複製程式碼
"use strict";
if (true) {
  function func() {
    //code
  }
}

程式碼會報錯,但ES2015不會,因為會解讀為函式在塊級作用域內宣告,但這時候,if後面大括號不能夠省略。

六.全域性屬性:

在全域性作用域使用var宣告的變數,也是全域性屬性,程式碼例項如下:

[JavaScript] 純文字檢視 複製程式碼執行程式碼
var antzone = "螞蟻部落";
console.log(window.antzone);

但是使用let宣告的變數並非如此,程式碼例項如下:

[JavaScript] 純文字檢視 複製程式碼執行程式碼
let url = "softwhy.com";
console.log(window.url);

七.塊級作用域的應用例項:

下面通過一個簡單的程式碼例項,演示一下塊級作用域的使用。

通過for迴圈批量為li元素註冊click事件處理函式,點選li元素會顯示對應的索引值。

[HTML] 純文字檢視 複製程式碼執行程式碼
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
<script>
window.onload=function(){
  var lis = document.getElementsByTagName("li");
  var odiv = document.getElementById("antzone");
  for (var index = 0; index < lis.length; index++) {
    lis[index].index = index;
    lis[index].onclick = function () {
      odiv.innerHTML = this.index;
    }
  }
}
</script>
</head>
<body>
<div id="antzone"></div>
<ul>
  <li>螞蟻部落一</li>
  <li>螞蟻部落二</li>
  <li>螞蟻部落三</li>
  <li>螞蟻部落四</li>
</ul>
</body>
</html>

var宣告變數不會產生塊級作用域,for迴圈完畢之後,index值最終是4,所以通過在li元素上自定義一個index屬性來儲存當前元素的索引的方式來實現我們的要求,當然也可以採用閉包的方式。如果採用let宣告,那麼就方便多了,程式碼如下:

[HTML] 純文字檢視 複製程式碼執行程式碼
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
<script>
window.onload=function(){
  var lis = document.getElementsByTagName("li");
  var odiv = document.getElementById("antzone");
  for (let index = 0; index < lis.length; index++) {
    lis[index].onclick = function () {
      odiv.innerHTML = index;
    }
  }
}
</script>
</head>
<body>
<div id="antzone"></div>
<ul>
  <li>螞蟻部落一</li>
  <li>螞蟻部落二</li>
  <li>螞蟻部落三</li>
  <li>螞蟻部落四</li>
</ul>
</body>
</html>

相關文章