vue|JavaScript let語法
vue|JavaScript let語法
let 語句宣告一個塊級作用域的本地變數,並且可選的將其初始化為一個值。
語法
<span style="color:#333333">let var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]];</span>
引數
var1
, var2
, …, varN
變數名。可以是任意合法的識別符號。
value1
, value2
, …, valueN
變數的初始值。可以是任意合法的表示式。
描述
let允許你宣告一個作用域被限制在塊級中的變數、語句或者表示式。與var關鍵字不同的是,var宣告的變數只能是全域性或者整個函式塊的。
點這裡可以明白我們為什麼選取“let”這個名字。
作用域規則
let宣告的變數只在其宣告的塊或子塊中可用,這一點,與var相似。二者之間最主要的區別在於var宣告的變數的作用域是整個封閉函式。
<span style="color:#333333"><code>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 }</code></span>
簡化內部函式程式碼
當用到內部函式的時候,let會讓你的程式碼更加簡單。
<span style="color:#333333"><code class="language-js"><span style="color:#0077aa">var</span> list <span style="color:#a67f59">=</span> document<span style="color:#999999">.</span><span style="color:#dd4a68">getElementById</span><span style="color:#999999">(</span><span style="color:#669900">"list"</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#0077aa">for</span> <span style="color:#999999">(</span><span style="color:#0077aa">let</span> i <span style="color:#a67f59">=</span> <span style="color:#990055">1</span><span style="color:#999999">;</span> i <span style="color:#a67f59"><=</span> <span style="color:#990055">5</span><span style="color:#999999">;</span> i<span style="color:#a67f59">++</span><span style="color:#999999">)</span> <span style="color:#999999">{</span> <span style="color:#0077aa">var</span> item <span style="color:#a67f59">=</span> document<span style="color:#999999">.</span><span style="color:#dd4a68">createElement</span><span style="color:#999999">(</span><span style="color:#669900">"LI"</span><span style="color:#999999">)</span><span style="color:#999999">;</span> item<span style="color:#999999">.</span><span style="color:#dd4a68">appendChild</span><span style="color:#999999">(</span>document<span style="color:#999999">.</span><span style="color:#dd4a68">createTextNode</span><span style="color:#999999">(</span><span style="color:#669900">"Item "</span> <span style="color:#a67f59">+</span> i<span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#0077aa">let</span> j <span style="color:#a67f59">=</span> i<span style="color:#999999">;</span> item<span style="color:#999999">.</span>onclick <span style="color:#a67f59">=</span> <span style="color:#0077aa">function</span> <span style="color:#999999">(</span>ev<span style="color:#999999">)</span> <span style="color:#999999">{</span> console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span><span style="color:#669900">"Item "</span> <span style="color:#a67f59">+</span> j <span style="color:#a67f59">+</span> <span style="color:#669900">" is clicked."</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#999999">}</span><span style="color:#999999">;</span> list<span style="color:#999999">.</span><span style="color:#dd4a68">appendChild</span><span style="color:#999999">(</span>item<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#999999">}</span></code></span>
上面這段程式碼的意圖是建立5個li,點選不同的li能夠打印出當前li的序號。如果不用let,而改用var的話,將總是打印出 Item 5 is Clicked,因為 j 是函式級變數,5個內部函式都指向了同一個 j ,而 j 最後一次賦值是5。用了let後,j 變成塊級域(也就是花括號中的塊,每進入一次花括號就生成了一個塊級域),所以 5 個內部函式指向了不同的 j 。
在程式或者函式的頂層,let並不會像var一樣在全域性物件上創造一個屬性,比如
<span style="color:#333333"><code class="language-js"><span style="color:#0077aa">var</span> x <span style="color:#a67f59">=</span> <span style="color:#669900">'global'</span><span style="color:#999999">;</span>
<span style="color:#0077aa">let</span> y <span style="color:#a67f59">=</span> <span style="color:#669900">'global'</span><span style="color:#999999">;</span>
console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span><span style="color:#0077aa">this</span><span style="color:#999999">.</span>x<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// "global"</span>
console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span><span style="color:#0077aa">this</span><span style="color:#999999">.</span>y<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// undefined</span></code></span>
模仿私有介面
在處理建構函式的時候,可以通過let宣告而不是閉包來建立私有介面。
var SomeConstructor;
{
let privateScope = {};
SomeConstructor = function SomeConstructor () {
this.someProperty = "foo";
privateScope.hiddenProperty = "bar";
}
SomeConstructor.prototype.showPublic = function () {
console.log(this.someProperty); // foo
}
SomeConstructor.prototype.showPrivate = function () {
console.log(privateScope.hiddenProperty); // bar
}
}
var myInstance = new SomeConstructor();
myInstance.showPublic();
myInstance.showPrivate();
console.log(privateScope.hiddenProperty); // error
let 的暫存死區與錯誤
在同一個函式或同一個作用域中用let重複定義一個變數將引起 TypeError
.
<span style="color:#333333"><code class="language-js"><span style="color:#0077aa">if</span> <span style="color:#999999">(</span>x<span style="color:#999999">)</span> <span style="color:#999999">{</span>
<span style="color:#0077aa">let</span> foo<span style="color:#999999">;</span>
<span style="color:#0077aa">let</span> foo<span style="color:#999999">;</span> <span style="color:#708090">// TypeError thrown.</span>
<span style="color:#999999">}</span></code></span>
在 ECMAScript 2015 中,let 繫結不受變數提升的約束,這意味著 let 宣告不會被提升到當前執行上下文的頂部。在塊中的變數初始化之前,引用它將會導致 ReferenceError(而使用 var 宣告變數則恰恰相反,該變數的值是 undefined )。這個變數處於從塊開始到 let 初始化處理的”暫存死區“之中。
<span style="color:#333333"><code class="language-js"><span style="color:#0077aa">function</span> <span style="color:#dd4a68">do_something</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>bar<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// undefined</span>
console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>foo<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// ReferenceError: foo is not defined</span>
<span style="color:#0077aa">var</span> bar <span style="color:#a67f59">=</span> <span style="color:#990055">1</span><span style="color:#999999">;</span>
<span style="color:#0077aa">let</span> foo <span style="color:#a67f59">=</span> <span style="color:#990055">2</span><span style="color:#999999">;</span>
<span style="color:#999999">}</span></code></span>
在 switch
宣告中你可能會遇到這樣的錯誤,因為一個switch只有一個作用塊.
<span style="color:#333333"><code class="language-js"><span style="color:#0077aa">switch</span> <span style="color:#999999">(</span>x<span style="color:#999999">)</span> <span style="color:#999999">{</span>
<span style="color:#0077aa">case</span> <span style="color:#990055">0</span><span style="color:#999999">:</span>
<span style="color:#0077aa">let</span> foo<span style="color:#999999">;</span>
<span style="color:#0077aa">break</span><span style="color:#999999">;</span>
<span style="color:#0077aa">case</span> <span style="color:#990055">1</span><span style="color:#999999">:</span>
<span style="color:#0077aa">let</span> foo<span style="color:#999999">;</span> <span style="color:#708090">// TypeError for redeclaration.</span>
<span style="color:#0077aa">break</span><span style="color:#999999">;</span>
<span style="color:#999999">}</span></code></span>
let後跟一個函式傳遞的引數時將導致迴圈內部報錯。
function go(n){
for (let n of n.a) { // TypeError: n is undefined
console.log(n);
}
}
go({a:[1,2,3]});
迴圈定義中的let作用域
迴圈體中是可以引用在for宣告時用let定義的變數,儘管let不是出現在大括號之間.(注:該方法在 火狐 45.4.0 ,Centos7 下,報錯 ReferenceError: can't access lexical declaration `i' before initialization)
<span style="color:#333333"><code class="language-js"><span style="color:#0077aa">var</span> i <span style="color:#a67f59">=</span> <span style="color:#990055">0</span><span style="color:#999999">;</span>
<span style="color:#0077aa">for</span> <span style="color:#999999">(</span><span style="color:#0077aa">let</span> i <span style="color:#a67f59">=</span> i<span style="color:#999999">;</span> i <span style="color:#a67f59"><</span> <span style="color:#990055">10</span><span style="color:#999999">;</span> i<span style="color:#a67f59">++</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>i<span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#999999">}</span></code></span>
注:以上 let 宣告的 i 將會變成 undefined;chrome 版本50.0.2661.102 (64-bit);推薦以下寫法:
<span style="color:#333333"><code class="language-html">var i = 0;
for (let l = i; l < 10; l++) {
console.log(l);
}</code></span>
域作用規則
<span style="color:#333333"><code class="language-html">for (let expr1; expr2; expr3) statement</code></span>
在這個例子中,expr2, expr3, 和 statement 都是包含在一個隱含域塊中,其中也包含了 expr1.
例子
let
對比 var
let的作用域是塊,而var的作用域是函式
<span style="color:#333333"><code class="language-js"><span style="color:#0077aa">var</span> a <span style="color:#a67f59">=</span> <span style="color:#990055">5</span><span style="color:#999999">;</span>
<span style="color:#0077aa">var</span> b <span style="color:#a67f59">=</span> <span style="color:#990055">10</span><span style="color:#999999">;</span>
<span style="color:#0077aa">if</span> <span style="color:#999999">(</span>a <span style="color:#a67f59">===</span> <span style="color:#990055">5</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
<span style="color:#0077aa">let</span> a <span style="color:#a67f59">=</span> <span style="color:#990055">4</span><span style="color:#999999">;</span> <span style="color:#708090">// The scope is inside the if-block</span>
<span style="color:#0077aa">var</span> b <span style="color:#a67f59">=</span> <span style="color:#990055">1</span><span style="color:#999999">;</span> <span style="color:#708090">// The scope is inside the function</span>
console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>a<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// 4</span>
console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>b<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// 1</span>
<span style="color:#999999">}</span>
console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>a<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// 5</span>
console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>b<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// 1</span></code></span>
let
在迴圈中
可以用 let 來代替 var ,在 for 定義塊中使用塊級變數.
<span style="color:#333333"><code class="language-js"><span style="color:#0077aa">for</span> <span style="color:#999999">(</span><span style="color:#0077aa">let</span> i <span style="color:#a67f59">=</span> <span style="color:#990055">0</span><span style="color:#999999">;</span> i <span style="color:#a67f59"><</span> <span style="color:#990055">10</span><span style="color:#999999">;</span> i<span style="color:#a67f59">++</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>i<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// 0, 1, 2, 3, 4 ... 9</span>
<span style="color:#999999">}</span>
console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>i<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// i is not defined</span></code></span>
非標準的 let 擴充套件
let塊(
let
block)
let blocks 在 Gecko 44 中已經廢除( bug 1167029) 。
let塊
提供了一種在塊的範圍內獲取變數的值,而不會影響塊外面名字相同的變數的值的方法。
語法
<span style="color:#333333">let (var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]]) block;</span>
描述
let 語句塊為變數提供了局部作用域。它的作用是在單一程式碼塊的詞法範圍內繫結零個或多個變數; 此外與普通語句塊沒有任何區別。需要特別注意的是, 在 let
語句塊內使用 var 宣告的變數,它的作用域與在 let 語句塊之外宣告沒有區別;這樣的變數仍然具有函式作用域。在使用 let
語句塊時,必須使用花括號,否則會導致語法錯誤。
例子
<span style="color:#333333"><code class="language-js"><span style="color:#0077aa">var</span> x <span style="color:#a67f59">=</span> <span style="color:#990055">5</span><span style="color:#999999">;</span>
<span style="color:#0077aa">var</span> y <span style="color:#a67f59">=</span> <span style="color:#990055">0</span><span style="color:#999999">;</span>
<span style="color:#0077aa">let</span> <span style="color:#999999">(</span>x <span style="color:#a67f59">=</span> x <span style="color:#a67f59">+</span> <span style="color:#990055">10</span><span style="color:#999999">,</span> y <span style="color:#a67f59">=</span> <span style="color:#990055">12</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>x <span style="color:#a67f59">+</span> y<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// 27</span>
<span style="color:#999999">}</span>
console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>x <span style="color:#a67f59">+</span> y<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// 5</span></code></span>
let 程式碼塊的規則與 JavaScript 中其他型別的程式碼塊相同。允許在塊內通過 let 關鍵字宣告區域性變數。
作用域規則
使用 let
語句塊繫結的變數,其作用域是 let
語句塊本身,與任何其內部語句塊的作用域一樣,除非在這些內部語句塊內又定義了同名的變數。
let
表示式( let expression)
let
expression 在 Gecko 41 已經廢除(bug 1023609)。
let
表示式 可以將變數的作用域僅作用於一條語句。
語法
<span style="color:#333333">let (var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]]) expression;</span>
例子
你可以在一條語句的範圍中使用 let
關鍵字來設立變數:
<span style="color:#333333"><code class="language-js"><span style="color:#0077aa">var</span> a <span style="color:#a67f59">=</span> <span style="color:#990055">5</span><span style="color:#999999">;</span>
<span style="color:#0077aa">let</span><span style="color:#999999">(</span>a <span style="color:#a67f59">=</span> <span style="color:#990055">6</span><span style="color:#999999">)</span> console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>a<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// 6</span>
console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>a<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// 5</span></code></span>
作用域規則
給定一個 let
表示式:
<span style="color:#333333"><code class="language-html">let (decls) expr</code></span>
這裡隱式建立了一個包圍 expr 的語句塊。
規範
Specification | Status | Comment |
---|---|---|
ECMAScript 2015 (6th Edition, ECMA-262) Let and Const Declarations |
Standard | Initial definition. Does not specify let expressions or let blocks. |
ECMAScript Latest Draft (ECMA-262) Let and Const Declarations |
Draft |
瀏覽器相容性
We're converting our compatibility data into a machine-readable JSON format. This compatibility table still uses the old format, because we haven't yet converted the data it contains. Find out how you can help!
Feature | Chrome | Edge | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|---|
Basic support | 41.0 | (Yes) | 44 (44) | 11 | 17 | ? |
Temporal dead zone | ? | (Yes) | 35 (35) | ? | ? | ? |
let expression |
未實現 | 未實現 | 未實現 | 未實現 | 未實現 | 未實現 |
let block |
未實現 | 未實現 | 未實現 | 未實現 | 未實現 | 未實現 |
Firefox-specific notes
- [1]: 只允許用在被
<script type="application/javascript;version=1.7">
包裹的程式碼塊中 (或者更高的 版本version)。當心,無論如何, 作為一個非標準特性, 很有可能會打破其他瀏覽器的支援。 XUL 指令碼標籤實現這些特性不需要特殊的塊。 請看 bug 932517和bug 932517。 - ES6 compliance for
let
in SpIderMonkey is tracked in bug 950547 and non-standard extensions are going to be removed in the future bug 1023609.
相關連結
var
const
- ES6 In Depth:
let
andconst
- Breaking changes in
let
andconst
in Firefox 44. - You Don't Know JS: Scope & Closures: Chapter 3: Function vs. Block Scope
文件標籤和貢獻者
標籤:
此頁面的貢獻者: ssttii, SphinxKnight, jcguang, mathxlee, ywjco, zhangchen, yingying, frankfang1990, swfbarhr, xgqfrms-GitHub, mr.code, artificial, leafdog,yangzongjie, ZhiRui, ZhanghaoH, ChuckZhang, Go7hic, highsea, panhezeng, kemchenj, lunix01, dondevi, hang, Rococolate, Ende93, ouonet, ziyunfei, WangZishi,Junjie_Wei, teoli, nightire
最後編輯者: ssttii, Sep 16, 2018, 11:54:20 PM
原文連結:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/let