




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
1、數(shù)組的解構(gòu)賦值基本用法ES6 允許按照一定模式,從數(shù)組和對象中提取值,對變量進行賦值,這被稱為解構(gòu)(Destructuring)。以前,為變量賦值,只能直接指定值。ES6 允許寫成下面這樣。上面代碼表示,可以從數(shù)組中提取值,按照對應(yīng)位置,對變量賦值。本質(zhì)上,這種寫法屬于“模式匹配”,只要等號兩邊的模式相同,左邊的變量就會被賦予對應(yīng)的值。下面是一些使用嵌套數(shù)組進行解構(gòu)的例子。如果解構(gòu)不成功,變量的值就等于 undefined。以上兩種情況都屬于解構(gòu)不成功,foo 的值都會等于undefined。var foo = ;var bar, foo = 1;let foo, bar, baz = 1,
2、2, 3;foo / 1bar / 2baz / 3let , , third = foo, bar, baz; third / bazlet x, , y = 1, 2, 3;x / 1y / 3let head, .tail = 1, 2, 3, 4;head / 1tail / 2, 3, 4let x, y, .z = a; x / ay / undefinedz / var a, b, c = 1, 2, 3;var a = 1;var b = 2;var c = 3;另一種情況是不完全解構(gòu),即等號左邊的模式,只匹配一部分的等號右邊的數(shù)組。這種情況下,解構(gòu)依然可以成功。上面兩個例子,
3、都屬于不完全解構(gòu),但是可以成功。如果等號的右邊不是數(shù)組(或者嚴(yán)格地說,不是可遍歷的結(jié)構(gòu),參見Iterator一章),那么將會報錯。上面的表達式都會報錯,因為等號右邊的值,要么轉(zhuǎn)為對象以后不具備 Iterator 接口(前五個表達式),要么本身就不具備Iterator 接口(最后一個表達式)。解構(gòu)賦值不僅適用于var 命令,也適用于let 和const 命令。對于Set 結(jié)構(gòu),也可以使用數(shù)組的解構(gòu)賦值。事實上,只要某種數(shù)據(jù)結(jié)構(gòu)具有Iterator 接口,都可以采用數(shù)組形式的解構(gòu)賦值。function* fibs() var a = 0;var b = 1; while (true) yield
4、a;a, b = b, a + b;var , second, third, fourth, fifth, sixth = fibs();sixth / 5let x, y, z = new Set(a, b, c);x / avar v1, v2, ., vN = array;let v1, v2, ., vN = array;const v1, v2, ., vN = array;/ 報錯 let foo = 1;let foo = false;let foo = NaN;let foo = undefined;let foo = null;let foo = ;let x, y = 1,
5、 2, 3;x / 1y / 2let a, b, d = 1, 2, 3, 4; a / 1b / 2d / 4上面代碼中,fibs 是一個Generator 函數(shù),原生具有Iterator 接口。解構(gòu)賦值會依次從這個接口獲取值。默認(rèn)值解構(gòu)賦值允許指定默認(rèn)值。注意,ES6嚴(yán)格相等運算符(=),判斷一個位置是否有值。所以,如果一個數(shù)組成員不嚴(yán)格等于 undefined,默認(rèn)值是不會生效的。上面代碼中,如果一個數(shù)組成員是 null,默認(rèn)值就不會生效,因為 null 不嚴(yán)格等于undefined。如果默認(rèn)值是一個表達式,那么這個表達式是惰性求值的,即只有在用到的時候,才會求值。上面代碼中,因為 x
6、 能取到值,所以函數(shù) f 根本不會執(zhí)行。上面的代碼其實等價于下面的代碼。默認(rèn)值可以解構(gòu)賦值的其他變量,但該變量必須已經(jīng)。let x;if (10 = undefined) x = f(); else x = 10;function f() console.log(aaa);let x = f() = 1;var x = 1 = undefined;x / 1var x = 1 = null; x / nullvar foo = true = ;foo / truex, y = b = a; / x=a, y=bx, y = b = a, undefined; / x=a, y=blet x =
7、 1, y = x = ;/ x=1; y=1let x = 1, y = x = 2;/;x=2; y=2let x = 1, y = x = 1, 2; / x=1; y=2let x = y, y = 1 =/ ReferenceError上面最后一個表達式之所以會報錯,是因為用到默認(rèn)值時,y 還沒有。對象的解構(gòu)賦值解構(gòu)不僅可以用于數(shù)組,還可以用于對象。對象的解構(gòu)與數(shù)組有一個重要的不同。數(shù)組的元素是按次序排列的,變量的取值由它的位置決定;而對象的屬性沒有次序,變量必須與屬性同名,才能取到正確的值。上面代碼的第一個例子,等號左邊的兩個變量的次序,與等號右邊兩個同名屬性的次序不一致,但是對取
8、值完全沒有影響。第二個例子的變量沒有對應(yīng)的同名屬性,導(dǎo)致取不到值,最后等于 undefined。如果變量名與屬性名不一致,必須寫成下面這樣。var foo: baz = foo: aaa, bar: bbb ;baz / aaalet obj = last: l = obj;: o, last: world ;let : f,f / ol / world這實際上說明,對象的解構(gòu)賦值是下面形式的簡寫(參見對象的擴展一章)。也就是說,對象的解構(gòu)賦值的機制,是先找到同名屬性,然后再賦給對應(yīng)的變量。真正被賦值的是后者,而不是前者。var foo: foo, bar: bar = foo: aaa, b
9、ar: bbb ;var bar, foo = foo: aaa, bar: bbb ;foo / aaabar / bbbvar baz = foo: aaa, bar: bbb ; baz / undefinedvar foo, bar = foo: aaa, bar: bbb ;foo / aaabar / bbbyx上面代碼中,真正被賦值的是變量,而不是模式。注意,采用這種寫法時,變量的和賦值是一體的。對于 let 和const 來說,變量不能重新,所以一旦賦值的變量以前過,就會報錯。上面代碼中,解構(gòu)賦值的變量都會重新,所以報錯了。不過,因為命令允許重新,所以這個錯誤只會在使用 let
10、 和 const 命令時出現(xiàn)。如果沒有第二個 let 命令,上面的代碼就不會報錯。和數(shù)組一樣,解構(gòu)也可以用于嵌套結(jié)構(gòu)的對象。o,x / oy / World注意,這時p 是模式,不是變量,因此不會被賦值。var node = loc: start: line: 1,column: 5;var loc: start: line = node; y: World ;var p: x, y = obj;var obj = p: let foo;(foo = foo: 1); / 成功 let baz;(bar: baz = bar: 1); /成功varlet foo;let foo = foo:
11、1; / SyntaxError: Duplicate declarationfoolet baz;let bar: baz = bar: 1; / SyntaxError: Duplicatedeclaration bazfoobazvar foo: baz = foo: aaa, bar: bbb ;baz / aaafoo / error: foo is not defined上面代碼中,只有是變量,和 start 都是模式,不會被賦值。下面是嵌套賦值的例子。對象的解構(gòu)也可以指定默認(rèn)值。默認(rèn)值生效的條件是,對象的屬性值嚴(yán)格等于 undefined。上面代碼中,如果x 屬性等于 null,
12、就不嚴(yán)格相等于undefined,導(dǎo)致默認(rèn)值不會生效。如果解構(gòu)失敗,變量的值等于 undefined。如果解構(gòu)模式是嵌套的對象,而且子對象所在的父屬性不存在,那么將會報錯。/ 報錯 var foo: bar = baz: baz;上面代碼中,等號左邊對象的 foo 屬性,對應(yīng)一個子對象。該子對象的 bar 屬性,解構(gòu)時會報錯。原因很簡單,因為 foo 這時等于 undefined,再取子屬性就會報錯,請看下面的代碼。var _tmp = baz: baz;var foo = bar: baz;foo / undefinedvar x = 3 = x: undefined; x / 3var x
13、 = 3 = x: null;x / nullvar x = 3 = ;x / 3var x, y = 5 = x: 1;x / 1y / 5var message: msg = Something went wrong = ; msg / Something went wronglet obj = ;let arr = ;( foo: p, bar: arr0 = foo: 123, bar: true );obj / prop:123arr / trueloclineline / 1loc / error: loc is undefinedstart / error: sta
14、rt is undefined如果要將一個已經(jīng)的變量用于解構(gòu)賦值,必須非常。上面代碼的寫報錯,因為JavaScript 引擎會將x理解成一個代碼塊,從而發(fā)生語法錯誤。只有不將大括號寫在行首,避免JavaScript 將其解釋為代碼塊,才能解決這個問題。/ 正確的寫法(x = x: 1);上面代碼將整個解構(gòu)賦值語句,放在一個圓括號里面,就可以正確執(zhí)行。關(guān)于圓括號與解構(gòu)賦值的關(guān)系,參見下文。解構(gòu)賦值允許,等號左邊的模式之中,不放置任何變量名。因此,可以寫出非常古怪的賦值表達式。( = true, false);( = abc);( = );上面的表達式雖然毫無意義,但是語法是合法的,可以執(zhí)行。對象
15、的解構(gòu)賦值,可以很方便地將現(xiàn)有對象的方法,賦值到某個變量。let log, sin, cos = Math;上面代碼將 Math 對象的對數(shù)、正弦、余弦三個方法,賦值到對應(yīng)的變量上,使用起來就會方便很多。字符串的解構(gòu)賦值字符串也可以解構(gòu)賦值。這是因為此時,字符串被轉(zhuǎn)換成了一個類似數(shù)組的對象。類似數(shù)組的對象都有一個 length 屬性,因此還可以對這個屬性解構(gòu)賦值。const a, b, c, d, e = o;a / hb / ec / ld / le / o/ 錯誤的寫法 var x;x = x: 1;/ SyntaxError: syntax error_tmp.foo.bar / 報錯數(shù)
16、值和布爾值的解構(gòu)賦值解構(gòu)賦值時,如果等號右邊是數(shù)值和布爾值,則會先轉(zhuǎn)為對象。s = Numbrototype.toString / truelet toString: s = true;s =.prototype.toString / true上面代碼中,數(shù)值和布爾值的包裝對象都有 toString 屬性,因此變量s 都能取到值。解構(gòu)賦值的規(guī)則是,只要等號右邊的值不是對象,就先將其轉(zhuǎn)為對象。由于 undefined和 null 無法轉(zhuǎn)為對象,所以對它們進行解構(gòu)賦值,都會報錯。函數(shù)參數(shù)的解構(gòu)賦值函數(shù)的參數(shù)也可以使用解構(gòu)賦值。上面代碼中,函數(shù) add 的參數(shù)表面上是一個數(shù)組,但在傳入?yún)?shù)的那一刻,
17、數(shù)組參數(shù)就被解變量x 和y。對于函數(shù)的代碼來說,它們能感受到的參數(shù)就是 x 和y。下面是另一個例子。1, 2, 3, 4.map(a, b) = a + b);/ 3, 7 function add(x, y) return x + y;add(1, 2); / 3let prop: x = undefined; / TypeErrorlet prop: y = null; /TypeErrorlet toString: s = 123;let length : len = o;len / 5函數(shù)參數(shù)的解構(gòu)也可以使用默認(rèn)值。上面代碼中,函數(shù) move 的參數(shù)是一個對象,通過對這個對象進行解構(gòu),
18、得到變量 x 和y 的值。如果解構(gòu)失敗,x 和y 等于默認(rèn)值。注意,下面的寫得到不一樣的結(jié)果。上面代碼是為函數(shù) move 的參數(shù)指定默認(rèn)值,而不是為變量x 和y 指定默認(rèn)值,所以會得到與前一種寫法不同的結(jié)果。undefined 就會觸發(fā)函數(shù)參數(shù)的默認(rèn)值。圓括號問題解構(gòu)賦值雖然很方便,但是起來并不容易。對于編譯器來說,一個式子到底是模式,還是表達式,沒有辦法從一開始就知道,必須到(或不到)等號才能知道。是,如果模式中出現(xiàn)圓括號怎么處理。ES6 的規(guī)則是,只要有可能導(dǎo)致由此帶來解構(gòu)的歧義,就不得使用圓括號。但是,這條規(guī)則實際上不那么容易辨別,處理起來相當(dāng)麻煩。因此,建議只要有可能,就不要在模式中放
19、置圓括號。1, undefined, 3.map(x = yes) = x);/ 1, yes, 3 function move(x, y = x: 0, y: 0 ) return x, y;move(x: 3, y: 8); / 3, 8move(x: 3); / 3, undefinedmove();/ undefined, undefinedmove(); / 0, 0function move(x = 0, y = 0 = ) return x, y;move(x: 3, y: 8); / 3, 8move(x: 3); / 3, 0move(); / 0,0move(); / 0,
20、 0不能使用圓括號的情況以下三種解構(gòu)賦值不得使用圓括號。(1)變量語句中,不能帶有圓括號。上面三個語句都會報錯,因為它們都是變量語句,模式不能使用圓括號。(2)函數(shù)參數(shù)中,模式不能帶有圓括號。函數(shù)參數(shù)也屬于變量,因此不能帶有圓括號。(3)賦值語句中,不能將整個模式,或嵌套模式中的一層,放在圓括號之中。上面代碼將整個模式放在圓括號之中,導(dǎo)致報錯。上面代碼將嵌套模式的一層,放在圓括號之中,導(dǎo)致報錯??梢允褂脠A括號的情況可以使用圓括號的情況只有一種:賦值語句的非模式部分,可以使用圓括號。(b) = 3; / 正確( p: (d) = ); / 正確(p) = 3;/ 正確/ 報錯(
21、 p: a ), x: c = , ;/ 全部報錯( p: a ) = p: 42 ;(a) = 5;/ 報錯function f(z) return z; / 全部報錯 var (a) = 1;var x: (c) = ;var (x: c) = ;var (x: c) = ;var (x): c = ; var o: ( p: p ) = o: p: 2 ;上面三行語句都可以正確執(zhí)行,因為首先它們都是賦值語句,而不是語句;其次它們的圓括號都不屬于模式的一部分。第一行語句中,模式是取數(shù)組的第一個成員,跟圓括號無關(guān);第二行語句中,模式是 p,而不是 d;第三行語句與第一行語句的性質(zhì)一致。用途變
22、量的解構(gòu)賦值用途很多。(1)交換變量的值上面代碼交換變量x 和y 的值,這樣的寫法不僅簡潔,而且易讀,語義非常清晰。(2)從函數(shù)返回多個值函數(shù)只能返回一個值,如果要返回多個值,只能將它們放在數(shù)組或?qū)ο罄锓祷?。有了解?gòu)賦值,取出這些值就非常方便。 return 1, 2, 3;var a, b, c = exle(); ;var foo, bar = exle();(3)函數(shù)參數(shù)的定義解構(gòu)賦值可以方便地將一組參數(shù)與變量名對應(yīng)起來。(4)提取 JSON 數(shù)據(jù)解構(gòu)賦值對提取JSON 對象中的數(shù)據(jù),尤其有用。/ 參數(shù)是一組有次序的值 function f(x, y, z) . f(1, 2, 3);/ 參數(shù)是一組無次序的值 function f(x, y, z) . f(z: 3, y: 2, x: 1);/ 返回一個對象function exle() return foo: 1,bar: 2/ 返回一個數(shù)組function exle() x, y = y, x;上面代碼可以快速提取JSON 數(shù)據(jù)的值。(5)函數(shù)參數(shù)的默認(rèn)值jQuery.ajax = function (url, async = true,beforeSend = function () , cache = true,complete = function () , cross= false,var jsonD
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 黑龍江工業(yè)學(xué)院《生物醫(yī)學(xué)信息與統(tǒng)計學(xué)》2023-2024學(xué)年第二學(xué)期期末試卷
- 陽光學(xué)院《流體傳動與控制基礎(chǔ)》2023-2024學(xué)年第二學(xué)期期末試卷
- 武漢海事職業(yè)學(xué)院《單片機原理與應(yīng)用綜合設(shè)計》2023-2024學(xué)年第二學(xué)期期末試卷
- 大興安嶺職業(yè)學(xué)院《企業(yè)電子產(chǎn)品設(shè)計與制造》2023-2024學(xué)年第二學(xué)期期末試卷
- 四川汽車職業(yè)技術(shù)學(xué)院《科學(xué)社會主義概論》2023-2024學(xué)年第二學(xué)期期末試卷
- 雙頭應(yīng)急燈項目效益評估報告
- 沈陽音樂學(xué)院《內(nèi)科護理學(xué)(2)》2023-2024學(xué)年第二學(xué)期期末試卷
- 鄭州商貿(mào)旅游職業(yè)學(xué)院《社會治理》2023-2024學(xué)年第二學(xué)期期末試卷
- 伊犁師范大學(xué)《中職英語微格教學(xué)技能訓(xùn)練》2023-2024學(xué)年第二學(xué)期期末試卷
- 人教版初中歷史與社會七年級上冊 3.5 干旱的寶地-塔里木盆地 教學(xué)設(shè)計
- 醫(yī)院骨科專病數(shù)據(jù)庫建設(shè)需求
- 三年級下冊混合計算100題及答案
- 中小學(xué)幼兒園安全風(fēng)險防控工作規(guī)范
- ESD技術(shù)要求和測試方法
- 正確認(rèn)識民族與宗教的關(guān)系堅持教育與宗教相分離
- 宜黃縣二都鎮(zhèn)高山飾面用花崗巖開采以及深加工項目環(huán)評報告
- 血液科護士的惡性腫瘤護理
- 畜禽廢棄物資源化利用講稿課件
- 土地糾紛調(diào)解簡單協(xié)議書
- 服裝倉庫管理制度及流程
- 《餐飲渠道開發(fā)方案》課件
評論
0/150
提交評論