ES6入門摘錄筆記(一)

讀阮老師的摘錄筆記^_^

一赤惊,let/const

1.1 let

let所聲明的變量敲长,只在let命令所在的代碼塊內有效醉鳖。
for循環(huán)還有一個特別之處捡硅,就是設置循環(huán)變量的那部分是一個父作用域,而循環(huán)體內部是一個單獨的子作用域盗棵。

for (let i = 0; i < 3; i++) {
  let i = 'abc';
  console.log(i);
}
// abc
// abc
// abc

var命令會發(fā)生”變量提升“現象壮韭,即變量可以在聲明之前使用,值為undefined纹因。let命令改變了語法行為喷屋,它所聲明的變量一定要在聲明后使用,否則報錯瞭恰,不存在變量提升屯曹。

暫時性死區(qū)(temporal dead zone,簡稱 TDZ)
只要塊級作用域內存在let命令惊畏,它所聲明的變量就“綁定”(binding)這個區(qū)域恶耽,不再受外部的影響⊙掌簦總之驳棱,在代碼塊內,使用let命令聲明變量之前农曲,該變量都是不可用的社搅。

var tmp = 123;

if (true) {
  tmp = 'abc'; // ReferenceError
  let tmp;
}

“暫時性死區(qū)”也意味著typeof不再是一個百分之百安全的操作。

typeof x; // ReferenceError
let x;

作為比較乳规,如果一個變量根本沒有被聲明形葬,使用typeof反而不會報錯。typeof undeclared_variable // "undefined" 所以暮的,在沒有l(wèi)et之前笙以,typeof運算符是百分之百安全的,永遠不會報錯《潮纾現在這一點不成立了猖腕。
另外下面的代碼也會報錯,與var的行為不同恨闪。

// 不報錯
var x = x;
// 報錯
let x = x;

不允許重復聲明
let不允許在相同作用域內倘感,重復聲明同一個變量。因此咙咽,不能在函數內部重新聲明參數老玛,除非在函數里面的子作用域聲明。

1.2 塊級作用域

ES6 允許塊級作用域的任意嵌套。內層作用域可以定義和外層作用域同名的變量蜡豹。塊級作用域的出現麸粮,實際上使得獲得廣泛應用的立即執(zhí)行函數表達式(IIFE)不再必要了。

ES5 規(guī)定镜廉,函數只能在頂層作用域和函數作用域之中聲明弄诲,不能在塊級作用域聲明。但是娇唯,瀏覽器沒有遵守這個規(guī)定客燕,為了兼容以前的舊代碼沸手,還是支持在塊級作用域之中聲明函數督勺。ES6 引入了塊級作用域蔬墩,明確允許在塊級作用域之中聲明函數敢茁,但是只在使用大括號的情況下成立佑淀,如果沒有使用大括號,就會報錯彰檬。ES6 規(guī)定伸刃,塊級作用域之中,函數聲明語句的行為類似于let逢倍,在塊級作用域之外不可引用捧颅。

為了減輕因此產生的不兼容問題,ES6在附錄B里面規(guī)定较雕,瀏覽器的實現可以有自己的行為方式碉哑。注意這幾條規(guī)定只對 ES6 的瀏覽器實現有效,其他環(huán)境的實現不用遵守亮蒋,還是將塊級作用域的函數聲明當作let處理扣典。

  • 允許在塊級作用域內聲明函數。
  • 函數聲明類似于var慎玖,即會提升到全局作用域或函數作用域的頭部贮尖。
  • 同時,函數聲明還會提升到所在的塊級作用域的頭部趁怔。

考慮到環(huán)境導致的行為差異太大湿硝,應該避免在塊級作用域內聲明函數。如果確實需要润努,也應該寫成函數表達式关斜,而不是函數聲明語句。

注:這一部分例子看教程代碼铺浇。

本質上蚤吹,塊級作用域是一個語句,將多個操作封裝在一起,沒有返回值裁着。用do表達式(提案)可以使塊級作用域可以變?yōu)楸磉_式繁涂。

let x = do {
  let t = f();
  t * t + 1;
};

1.3 const命令

const聲明的變量不得改變值,這意味著二驰,const一旦聲明變量扔罪,就必須立即初始化,不能留到以后賦值桶雀。

const實際上保證的矿酵,并不是變量的值不得改動,而是變量指向的那個內存地址不得改動矗积。對于簡單類型的數據(數值全肮、字符串、布爾值)棘捣,值就保存在變量指向的那個內存地址辜腺,因此等同于常量。但對于復合類型的數據(主要是對象和數組)乍恐,變量指向的內存地址评疗,不能控制指向值是否可變。因此茵烈,將一個對象聲明為常量必須非常小心百匆。

如果真的想將對象凍結,應該使用Object.freeze方法呜投。除了將對象本身凍結加匈,對象的屬性也應該凍結。

ES5 只有兩種聲明變量的方法:var命令和function命令仑荐。ES6除了添加let和const命令矩动,后面章節(jié)還會提到,另外兩種聲明變量的方法:import命令和class命令释漆。所以悲没,ES6 一共有6種聲明變量的方法

1.4 頂層對象的屬性

ES5之中男图,頂層對象的屬性與全局變量是等價的示姿。

頂層對象的屬性與全局變量掛鉤,被認為是JavaScript語言最大的設計敗筆之一逊笆。ES6為了改變這一點栈戳,一方面規(guī)定,為了保持兼容性难裆,var命令和function命令聲明的全局變量子檀,依舊是頂層對象的屬性镊掖;另一方面規(guī)定,let命令褂痰、const命令亩进、class命令聲明的全局變量,不屬于頂層對象的屬性缩歪。

1.5 global對象

ES5 的頂層對象归薛,本身也是一個問題,因為它在各種實現里面是不統(tǒng)一的匪蝙。

  • 瀏覽器里面主籍,頂層對象是window,但 Node 和 Web Worker 沒有window逛球。
  • 瀏覽器和 Web Worker 里面千元,self也指向頂層對象,但是 Node 沒有self颤绕。
  • Node 里面幸海,頂層對象是global,但其他環(huán)境都不支持屋厘。

同一段代碼為了能夠在各種環(huán)境,都能取到頂層對象月而,現在一般是使用this變量汗洒,但是有局限性。

  • 全局環(huán)境中父款,this會返回頂層對象溢谤。但是,Node 模塊和 ES6 模塊中憨攒,this返回的是當前模塊世杀。
  • 函數里面的this,如果函數不是作為對象的方法運行肝集,而是單純作為函數運行瞻坝,this會指向頂層對象。但是杏瞻,嚴格模式下所刀,這時this會返回undefined。
  • 不管是嚴格模式捞挥,還是普通模式浮创,new Function('return this')(),總是會返回全局對象砌函。但是斩披,如果瀏覽器用了CSP(Content Security Policy溜族,內容安全政策),那么eval垦沉、new Function這些方法都可能無法使用煌抒。

現在有一個提案,在語言標準的層面乡话,引入global作為頂層對象摧玫。也就是說,在所有環(huán)境下绑青,global都是存在的诬像,都可以從它拿到頂層對象。墊片庫system.global模擬了這個提案闸婴,可以在所有環(huán)境拿到global坏挠。

二,變量的解構(Destructuring)賦值

2.1 數組的解構賦值

ES6 允許寫成下面這樣let [a, b, c] = [1, 2, 3];邪乍。本質上降狠,這種寫法屬于“模式匹配”。

如果解構不成功庇楞,變量的值就等于undefined榜配。

let [foo] = [];
let [bar, foo] = [1];

另一種情況是不完全解構,即等號左邊的模式吕晌,只匹配一部分的等號右邊的數組。這種情況下睛驳,解構依然可以成功。

let [a, [b], d] = [1, [2, 3], 4];
a // 1
b // 2
d // 4

如果等號的右邊不是數組(或者嚴格地說乏沸,不是可遍歷的結構,參見《Iterator》一章)蹬跃,那么將會報錯。對于 Set 結構還有generator函數蝶缀,也可以使用數組的解構賦值。事實上扼劈,只要某種數據結構具有 Iterator 接口,都可以采用數組形式的解構賦值荐吵。

解構賦值允許指定默認值骑冗。但是要注意條件:注意,ES6 內部使用嚴格相等運算符(===)贼涩,判斷一個位置是否有值;所以遥倦,如果一個數組成員不嚴格等于undefined,默認值是不會生效的袒哥。

let [x, y = 'b'] = ['a']; // x='a', y='b'
let [x = 1] = [undefined]; x // 1
let [x = 1] = [null]; x // null

如果默認值是一個表達式,那么這個表達式是惰性求值的堡称,即只有在用到的時候(等號那邊是undefined)瞎抛,才會求值。默認值可以引用解構賦值的其他變量却紧,但該變量必須已經聲明桐臊。let [x = 1, y = x] = []; // x=1; y=1.

2.2 對象的解構賦值

對象的屬性沒有次序,變量必須與屬性同名晓殊,才能取到正確的值断凶。
如果變量名與屬性名不一致,必須寫成下面這樣巫俺。
這實際上說明认烁,對象的解構賦值是下面形式的簡寫(參見《對象的擴展》一章)。let { foo: foo, bar: bar } = { foo: "aaa", bar: "bbb" };
也就是說识藤,對象的解構賦值的內部機制砚著,是先找到同名屬性次伶,然后再賦給對應的變量痴昧。真正被賦值的是后者,而不是前者冠王。

let { foo: baz } = { foo: "aaa", bar: "bbb" };
baz // "aaa"
foo // error: foo is not defined

上面代碼中赶撰,foo是匹配的模式,baz才是變量柱彻。

與數組一樣豪娜,解構也可以用于嵌套結構的對象。如果p也要作為變量賦值哟楷,可以寫成下面這樣瘤载。

let obj = {
  p: [
    'Hello',
    { y: 'World' }
  ]
};

let { p, p: [x, { y }] } = obj;
x // "Hello"
y // "World"
p // ["Hello", {y: "World"}]

對象的解構也可以指定默認值。默認值生效的條件是卖擅,對象的屬性值嚴格等于undefined鸣奔。如果解構失敗墨技,變量的值等于undefined。如果解構模式是嵌套的對象挎狸,而且子對象所在的父屬性不存在扣汪,那么將會報錯。// 報錯 let {foo: {bar}} = {baz: 'baz'};锨匆。

如果要將一個已經聲明的變量用于解構賦值崭别,必須非常小心。

// 錯誤的寫法
let x;
{x} = {x: 1};
// SyntaxError: syntax error
// 正確的寫法
let x;
({x} = {x: 1});

上面第一個代碼的寫法會報錯恐锣,因為 JavaScript 引擎會將{x}理解成一個代碼塊茅主,從而發(fā)生語法錯誤。然后代碼將整個解構賦值語句侥蒙,放在一個圓括號里面暗膜,就可以正確執(zhí)行。

解構賦值允許等號左邊的模式之中鞭衩,不放置任何變量名。因此论衍,可以寫出非常古怪的賦值表達式坯台。({} = [true, false]);

對象的解構賦值,可以很方便地將現有對象的方法稠炬,賦值到某個變量首启。

let { log, sin, cos } = Math;

由于數組本質是特殊的對象毅桃,因此可以對數組進行對象屬性的解構准夷。

2.3 字符串的解構賦值

字符串也可以解構賦值。這是因為字符串被轉換成了一個類似數組的對象读宙。const [a, b, c, d, e] = 'hello'; a // "h" b // "e" c // "l" d // "l" e // "o"结闸。

類似數組的對象都有一個length屬性,因此還可以對這個屬性解構賦值幔亥。let {length : len} = 'hello'; len // 5察纯。

2.4 數值和布爾值的解構賦值

解構賦值時饼记,如果等號右邊是數值和布爾值,則會先轉為對象即纲。

let {toString: s} = 123;
s === Number.prototype.toString // true

解構賦值的規(guī)則是低斋,只要等號右邊的值不是對象或數組匪凡,就先將其轉為對象病游。由于undefined和null無法轉為對象,所以對它們進行解構賦值买猖,都會報錯玉控。

2.5 函數參數的解構賦值

函數參數的解構也可以使用默認值奸远。undefined就會觸發(fā)函數參數的默認值。

function add([x, y]){
  return x + y;
}
add([1, 2]); // 3

注意下面兩種寫法丸冕,第一種x和y等于默認值胖烛,第二種是為函數move的參數指定默認值诅迷。

//first
function move({x = 0, y = 0} = {}) {
  return [x, y];
}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, 0]
move({}); // [0, 0]
move(); // [0, 0]

//second
function move({x, y} = { x: 0, y: 0 }) {
  return [x, y];
}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, undefined]
move({}); // [undefined, undefined]
move(); // [0, 0]

這個例子中是函數參數默認值可以與解構賦值的默認值罢杉,結合起來使用滩租。

2.6 圓括號

建議只要有可能律想,就不要在模式中放置圓括號绍弟。

以下三種解構賦值不得使用圓括號:(a)變量聲明語句 (b)函數參數 /其實也屬于變量聲明/(c)賦值語句的模式 /如([a]) = [5];/
這里不得使用是指整個或者一部分放置圓括號都不行。

可以使用圓括號的情況只有一種:賦值語句的非模式部分樟遣,可以使用圓括號。

[(b)] = [3]; // 正確
({ p: (d) } = {}); // 正確

上面三行語句都可以正確執(zhí)行澈歉,因為首先它們都是賦值語句屿衅,而不是聲明語句;其次它們的圓括號都不屬于模式的一部分涡尘。第一行語句中响迂,模式是取數組的第一個成員,跟圓括號無關川梅;第二行語句中然遏,模式是p,而不是d丢早。

2.7 變量解構賦值的用途

(1)交換變量的值(2)從函數返回多個值(3)函數參數的定義(4)提取JSON數據(5)函數參數的默認值(6)遍歷Map結構(7)輸入模塊的指定方法

在 es5 時代怨酝,如果想給一個函數默認值的話必須要這樣寫

var es5Fun = function (config) {
    var foo = config.foo || 'default foo'
    console.log(foo)
}

在 es6 有了結構賦值之后,傳入的參數可以自動賦予默認值

const es6Fun = ({foo = 'default foo'} = {}) => {
    console.log(foo)
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末赡艰,一起剝皮案震驚了整個濱河市瞄摊,隨后出現的幾起案子换帜,更是在濱河造成了極大的恐慌鹤啡,老刑警劉巖递瑰,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件抖部,死亡現場離奇詭異,居然都是意外死亡乡恕,警方通過查閱死者的電腦和手機俯萎,發(fā)現死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門函卒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人报嵌,你說我怎么就攤上這事锚国±春颍” “怎么了逸雹?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長园欣。 經常有香客問我休蟹,道長赂弓,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任翔怎,我火速辦了婚禮赤套,結果婚禮上珊膜,老公的妹妹穿的比我還像新娘。我一直安慰自己剔氏,他們只是感情好介蛉,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布溶褪。 她就那樣靜靜地躺著,像睡著了一般吹菱。 火紅的嫁衣襯著肌膚如雪彭则。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天输瓜,我揣著相機與錄音搔啊,去河邊找鬼。 笑死负芋,一個胖子當著我的面吹牛旧蛾,可吹牛的內容都是我干的锨天。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼迟赃!你這毒婦竟也來了纤壁?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤欠痴,失蹤者是張志新(化名)和其女友劉穎喇辽,沒想到半個月后菩咨,有當地人在樹林里發(fā)現了一具尸體抽米,經...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡云茸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年标捺,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嗤疯。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡萍倡,死狀恐怖辟汰,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情戴而,我是刑警寧澤所意,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布扶踊,位于F島的核電站秧耗,受9級特大地震影響舶治,放射性物質發(fā)生泄漏。R本人自食惡果不足惜霉猛,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一瘫辩、第九天 我趴在偏房一處隱蔽的房頂上張望杭朱。 院中可真熱鬧弧械,春花似錦空民、人聲如沸刃唐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽画饥。三九已至衔瓮,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間抖甘,已是汗流浹背热鞍。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留衔彻,地道東北人薇宠。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像艰额,于是被迫代替她去往敵國和親澄港。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內容