title: let和const命令
date: 2015-12-19 20:18:38
categories: tech
tags: ES2015
toc: true數組
{ let a = 10; var b = 1; } a // ReferenceError: a is not defined. b // 1
適合在for
循環中使用,只在循環內部有效。閉包
for(let i = 0; i < arr.length; i++){} console.log(i) //ReferenceError: i is not defined
下面的代碼若是使用var,最後輸出的是10。函數
var a = []; for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 10
上面代碼中,變量i是var聲明的,在全局範圍內都有效。因此每一次循環,新的i值都會覆蓋舊值,致使最後輸出的是最後一輪的i的值。
若是使用let,聲明的變量僅在塊級做用域內有效,最後輸出的是6。code
var a = []; for (let i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 6
let實際上爲JavaScript新增了塊級做用域。對象
function fn() { let n = 5; if (true) { let n = 10; } console.log(n); // 5 }
上面的函數有兩個代碼塊,都聲明瞭變量n,運行後輸出5。這表示外層代碼塊不受內層代碼塊的影響。若是使用var定義變量n,最後輸出的值就是10。ip
塊級做用域很犀利,界限劃得很清楚。感受沒有沒閉包
什麼事的樣子。若是確實須要調用,就要像下面這樣處理。作用域
let f; { let a = 'secret'; f = function () { return a; } } f() // "secret"
上面代碼中,變量i是let聲明的,當前的i只在本輪循環有效,因此每一次循環的i其實都是一個新的變量,因此最後輸出的是6。字符串
function bar(x = y, y = 2) { return [x, y]; } bar(); // [ undefined, 2 ]
上面代碼中,調用bar函數之因此報錯,是由於參數x默認值等於另外一個參數y,而此時y尚未聲明,屬於」死區「。若是y的默認值是x,就不會報錯,由於此時x已經聲明瞭。it
function bar(x = 2, y = x) { return [x, y]; } bar(); // [2, 2]
暫時性死區最簡單理解可能就是是否
以前聲明過,否
則爲死區。io
const也用來聲明變量,可是聲明的是常量。一旦聲明,常量的值就不能改變。
const PI = 3.1415; PI // 3.1415 PI = 3; // TypeError: "PI" is read-only
上面代碼代表改變常量的值會報錯。
const聲明的變量不得改變值,這意味着,const一旦聲明變量,就必須當即初始化,不能留到之後賦值。
const foo; // SyntaxError: missing = in const declaration
上面代碼表示,對於const來講,只聲明不賦值,就會報錯
const與let命令相同點
只在聲明所在的塊級做用域內有效
存在暫時性死區(即便用變量要提早聲明)
不可重複聲明
通常來說,const
定義基本類型不在改變的值,好比字符串,數字等。
可是若是定義引用類型,好比普通對象{}
或數組[]
。好比
const foo = {};
foo
這個地址在棧區
已經被const
定死,不容改變,不然即爲報錯。
可是引用類型是能夠改變的,由於它們地址在堆區
。
const foo = {}; foo.prop = 123; console.log(foo.prop) // 123 console.log(foo) // { prop: 123 }
由於使用const就是想把它規定死,常量。下面方法能夠實現
const bar = Object.freeze({}); bar.name = 'joe'; console.log(bar.name); //TypeError: Can't add property name, object is not extensible
ES5聲明變量的方法
var
function
ES6新增聲明變量的方法
let
const
class
import