let和const命令
1. let命令
只要塊級作用域內(nèi)存在let命令馋艺,它所聲明的變量就“綁定”這個區(qū)域夸研,不再受外部的影響骚揍。
ES6明確規(guī)定永部,如果區(qū)塊總存在let和const命令独泞,這個區(qū)塊對這些命令聲明的變量,從一開始就形成了封閉作用域苔埋。凡是在聲明之前就使用這些變量懦砂,就會報(bào)錯。
- 不存在變量提升组橄。
- 聲明前被使用屬于暫時性死區(qū)荞膘,報(bào)錯。
- 不允許重復(fù)聲明玉工。
//報(bào)錯
function () {
let a = 10;
var a = 1;
}
//報(bào)錯
function() {
let a = 10;
let a = 1;
}
2. 塊級作用域
- ES6允許塊級作用域的任意嵌套羽资。外層作用域無法讀取內(nèi)層作用域的變量。
- 內(nèi)層作用域可以定義外層作用域的同名變量遵班。
- ES6中屠升,塊級作用域聲明的函數(shù)類似于let,對作用域之外沒有影響狭郑。
- ES6明確允許在塊級作用域中可以聲明函數(shù)腹暖。
- 函數(shù)聲明類似var,即會提升到全局作用域或函數(shù)作用域的頭部翰萨。
- 函數(shù)聲明還會提升到所在的塊級作用域的頭部脏答。
注意:以上最后三條只對ES6的瀏覽器實(shí)現(xiàn)有效。
3. const命令
- const聲明一個只讀的常量缨历,一旦聲明以蕴,不能改變。
- const一旦聲明變量辛孵,必須立即初始化丛肮。
- const的作用域和let相同,只在聲明所在的塊級作用域有效魄缚。
- const命令聲明的常量也是不提升宝与,存在暫時性死區(qū)焚廊,只能在聲明的位置后面使用。
- const聲明的常量與let一樣不可重復(fù)聲明习劫。
- 對于復(fù)合類型的變量咆瘟,變量名不指向數(shù)字,而是志向地址诽里。const只需保證地址不變袒餐,數(shù)據(jù)可變。
const a = [];
a.push("abc"); //可執(zhí)行
a.length = 0; //可執(zhí)行
a = ['Dave']; //報(bào)錯
- 如想講對象凍結(jié)谤狡,使用object.freeze方法
const foo = object.freeze({});
//常規(guī)模式時灸眼,下一行不起作用;
//嚴(yán)格模式時墓懂,改行報(bào)錯焰宣。
foo.prop = 123;
4. 頂層對象的屬性
- ES5中,頂層對象的屬性與全局變量是等價的捕仔。(不推薦不聲明直接用變量)
- ES6修正匕积,var命令和function命令聲明的全局變量,依舊是頂層對象的屬性榜跌;let命令闪唆、const命令、class命令聲明的全局變量钓葫,不屬于頂層對象的屬性苞氮。
5. 頂層對象
ES5的頂層對象,本身也是一個問題瓤逼,因?yàn)樗诟鞣N實(shí)現(xiàn)里面是不統(tǒng)一的。
- 瀏覽器里面库物,頂層對象是window霸旗,但Node和Web Worker沒有window。
- 瀏覽器和Web Worker里面戚揭,self也指向頂層對象诱告,但是Node沒有self。
- Node里面民晒,頂層對象是global精居,但其他環(huán)境都不支持。
同一段代碼為了能夠在各種環(huán)境潜必,都能取到頂層對象靴姿,現(xiàn)在一般是使用this變量,但是有局限性磁滚。
- 全局環(huán)境中佛吓,this會返回頂層對象宵晚。但是,Node模塊和ES6模塊中维雇,this返回的是當(dāng)前模塊淤刃。
- 函數(shù)里面的this,如果函數(shù)不是作為對象的方法運(yùn)行吱型,而是單純作為函數(shù)運(yùn)行逸贾,this會指向頂層對象。但是津滞,嚴(yán)格模式下铝侵,這時this會返回undefined。
- 不管是嚴(yán)格模式据沈,還是普通模式哟沫,new Function('return this')(),總是會返回全局對象锌介。但是嗜诀,如果瀏覽器用了CSP(Content Security Policy,內(nèi)容安全政策)孔祸,那么eval隆敢、new Function這些方法都可能無法使用。
下面是兩種勉強(qiáng)可以使用的方法崔慧。
// 方法一
(typeof window !== 'undefined'
? window
: (typeof process === 'object' &&
typeof require === 'function' &&
typeof global === 'object')
? global
: this);
// 方法二
var getGlobal = function () {
if (typeof self !== 'undefined') { return self; }
if (typeof window !== 'undefined') { return window; }
if (typeof global !== 'undefined') { return global; }
throw new Error('unable to locate global object');
};
現(xiàn)在有一個[提案]拂蝎,在語言標(biāo)準(zhǔn)的層面,引入global作為頂層對象惶室。也就是說温自,在所有環(huán)境下,global都是存在的皇钞,都可以從它拿到頂層對象悼泌。
// CommonJS的寫法
require('system.global/shim')();
// ES6模塊的寫法
import shim from 'system.global/shim'; shim();
下面代碼將頂層對象放入變量global中
// CommonJS的寫法
var global = require('system.global')();
// ES6模塊的寫法
import getGlobal from 'system.global';
const global = getGlobal();