1. 程式人生 > >vue|JavaScript let語法

vue|JavaScript let語法

vue|JavaScript   let語法

let 語句宣告一個塊級作用域的本地變數,並且可選的將其初始化為一個值。

語法

<span style="color:#333333">let var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]];</span>

引數

var1var2, …, varN

變數名。可以是任意合法的識別符號。

value1value2, …, 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 932517bug 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.

相關連結

文件標籤和貢獻者

 標籤:  

 此頁面的貢獻者: ssttiiSphinxKnightjcguangmathxleeywjcozhangchenyingyingfrankfang1990swfbarhrxgqfrms-GitHubmr.codeartificialleafdog,yangzongjieZhiRuiZhanghaoHChuckZhangGo7hichighseapanhezengkemchenjlunix01dondevihangRococolateEnde93ouonetziyunfeiWangZishi,Junjie_Weiteolinightire

 最後編輯者: ssttii, Sep 16, 2018, 11:54:20 PM

 

 

原文連結:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/let