摘要:學(xué)習(xí)筆記變量析構(gòu)允許按照一定模式,從數(shù)組和對象中提取值,對變量進行賦值,這被稱為解構(gòu)。有一個屬性用屬性來獲取字符串長度數(shù)值和布爾值的解構(gòu)賦值解構(gòu)賦值時,如果等號右邊是數(shù)值和布爾值,則會先轉(zhuǎn)為對象。
es6學(xué)習(xí)筆記-變量析構(gòu)_v1.0
ES6 允許按照一定模式,從數(shù)組和對象中提取值,對變量進行賦值,這被稱為解構(gòu)(Destructuring)。
如果解構(gòu)失敗,變量的值等于undefined。
數(shù)組的解構(gòu)賦值"模式匹配",只要等號兩邊的模式相同,左邊的變量就會被賦予對應(yīng)的值。
let [a, b, c] = [1, 2, 3]; //相當(dāng)于對號入座,一個蘿卜一個坑 let [foo, [[bar], baz]] = [1, [[2], 3]]; //本質(zhì)上也是對號入座了 console.log(foo) // 1 console.log(bar) // 2 console.log(baz) // 3 let [ , , third] = ["foo", "bar", "baz"]; console.log(third) // "baz" let [x, , y] = [1, 2, 3]; //中間的變量空了,也自然跳過了中間的,然后直接賦值后面的 console.log(x) // 1 console.log(y) // 3 let [head, ...tail] = [1, 2, 3, 4]; //三個點號是用來擴展為一個數(shù)組序列的 console.log(head) // 1 console.log(tail) // [2, 3, 4],可以看到這里也是一個數(shù)組 let [x, y, ...z] = ["a"]; //因為其他沒有值,所以都會變成undefined或者空數(shù)組,沒辦法對號入座 console.log(x); //a console.log(y); // undefined console.log(z);//[] let [bar, foo] = [1]; //解構(gòu)不成功的的值就是undefined console.log(bar); //1 console.log(foo); // undefined
擴展運算符( spread )是三個點(...)。它好比 rest 參數(shù)的逆運算,將一個數(shù)組轉(zhuǎn)為用逗號分隔的參數(shù)序列,即把數(shù)組或類數(shù)組對象展開成一系列用逗號隔開的值,看解釋以為是變成了值,其實不然,看輸出就知道,其實也是一個數(shù)組
事實上,只要某種數(shù)據(jù)結(jié)構(gòu)具有 Iterator 接口,都可以采用數(shù)組形式的解構(gòu)賦值。
function * fibs() { //函數(shù)有* 是因為他是一個Generator,暫時忽略 let a = 0; let b = 1; while (true) { yield a; [a, b] = [b, a + b]; } } let [first, second, third, fourth, fifth, sixth] = fibs(); console.log(sixth) // 5
fibs是一個 Generator 函數(shù)(參見《Generator 函數(shù)》一章),原生具有 Iterator 接口。解構(gòu)賦值會依次從這個接口獲取值。
數(shù)組解構(gòu)默認值其實在這里只要大概理解他們的數(shù)據(jù)結(jié)構(gòu)差不多是上面那種類型的時候,就能時候數(shù)組結(jié)構(gòu)方式
默認值,主要是看左邊是否能取到右邊的值
let [foo = true] = []; //空數(shù)組,觸發(fā)默認值 console.log(foo) // true let [x, y = "b"] = ["a"]; //因為少了一個值,所以也觸發(fā)默認值 console.log(x); console.log(y);// x="a", y="b" let [x, y = "b"] = ["a", undefined]; //這里也觸發(fā)了,即使是undefined的值 console.log(x); console.log(y);// x="a", y="b" let [x = 1] = [undefined]; console.log(x) // 1 let [y = 1] = [null]; //正如下面提到,數(shù)組成員null的不觸發(fā)默認值 console.log(y) // null function f() { console.log("aaa"); } //這里主要是看x能取值,右邊的值是很正常能取到的,所以不會觸發(fā)默認值 let [x = f()] = [1]; console.log(x);//1 let [x = 1, y = x] = [];//因為沒有值,所以觸發(fā)默認值,然后x先于y聲明,所以y也可以使用x的值 console.log(x) console.log(y)// x=1; y=1 let [x = 1, y = x] = [2]; //因為有值,并且能對應(yīng)到x,并且先于y聲明 console.log(x) console.log(y)// x=2; y=2 let [x = 1, y = x] = [1, 2]; // x=1; y=2 let [x = y, y = 1] = []; // ReferenceError
對象的解構(gòu)賦值ES6 內(nèi)部使用嚴格相等運算符(===),判斷一個位置是否有值。
如果一個數(shù)組成員是null,默認值就不會生效,因為null不嚴格等于undefined。
對象的解構(gòu)與數(shù)組有一個重要的不同。數(shù)組的元素是按次序排列的,變量的取值由它的位置決定;而對象的屬性沒有次序,變量必須與屬性同名,才能取到正確的值。
如果變量名與屬性名不一致,需要利用原來的屬性(鍵)來中轉(zhuǎn),對象的解構(gòu)賦值的內(nèi)部機制,是先找到同名屬性,然后再賦給對應(yīng)的變量。
let { bar, foo } = { foo: "aaa", bar: "bbb" }; console.log(foo) // "aaa" console.log(bar) // "bbb" console.log(baz) // undefined,并且報錯,這里沒對應(yīng)上對象的鍵,所以沒有取到值 let obj = { first: "hello", last: "world" }; let { first: f, last: l } = obj; //這里的first就是原來的屬性,現(xiàn)在要提取值到新的變量f,要這樣寫 console.log(f) // "hello" console.log(l) // "world" let obj = { p: [ //真正對應(yīng)的是p里面的東西,因為下面p只是作為模式使用 "Hello", //對應(yīng)x { y: "World" } //對應(yīng){y} ] }; let { p: [x, { y }] } = obj; //這里需要注意,p是模式,因為有冒號,而且位于左邊 console.log(x) // "Hello" console.log(y) // "World" console.log(p) // p is not defined,這里p沒有定義 let obj = {}; let arr = []; //對于obj,這里直接對應(yīng)的是obj的屬性prop,而bar是對應(yīng)arr的第一個元素的值 ({ foo: obj.prop, bar: arr[0] } = { foo: 123, bar: true }); //很方便的直接賦值給對象屬性和數(shù)組的元素的值 console.log(obj) // {prop:123} console.log(arr) // [true],因為這個數(shù)組只有一個值對象解構(gòu)的默認值
大部分情況跟數(shù)組的結(jié)構(gòu)默認值類似,也是通過判斷是否undefined
let {x = 3} = {}; console.log(x) // 3 let {x, y = 5} = {x: 1}; console.log(x) // 1 console.log(y) // 5 //如果解構(gòu)模式是嵌套的對象,而且子對象所在的父屬性不存在,那么將會報錯。 //等號左邊對象的foo屬性,對應(yīng)一個子對象。該子對象的bar屬性,解構(gòu)時會報錯。 //因為foo這時等于undefined,(沒有對象然后直接去對象屬性)再取子屬性就會報錯,請看下面的代碼。 let {foo: {bar}} = {baz: "baz"};// 報錯對象的結(jié)構(gòu)的方便用法
對象的解構(gòu)賦值,可以很方便地將現(xiàn)有對象的方法,賦值到某個變量。
let { log, sin, cos } = Math; //這里直接使用了log和sin方法了 console.log(log(10));//2.302585092994046 console.log(sin(10));//-0.5440211108893698
對數(shù)組進行對象屬性結(jié)構(gòu)
let arr = [1, 2, 3]; //并且能夠使用數(shù)組的基本數(shù)字鍵來做匹配,0,1,2的數(shù)組索引數(shù)字鍵 let {0 : first, [arr.length - 1] : last} = arr; //這里支持一些方法,例如length,需要用[]括起來 console.log(first) // 1 console.log(last) // 3字符串的結(jié)構(gòu)賦值
字符串被轉(zhuǎn)換成了一個類似數(shù)組的對象。
有一個length屬性
const [a, b, c, d, e] = "hello"; a // "h" b // "e" c // "l" d // "l" e // "o" let {length : len} = "hello"; //用length屬性來獲取字符串長度 len // 5數(shù)值和布爾值的解構(gòu)賦值
解構(gòu)賦值時,如果等號右邊是數(shù)值和布爾值,則會先轉(zhuǎn)為對象。
數(shù)值和布爾值的包裝對象都有toString屬性
let {toString: s} = 123; //全等證明有這個toString屬性 console.log(s === Number.prototype.toString )// true console.log(s) //[Function: toString] let {toString: s} = true; console.log(s === Boolean.prototype.toString) // true console.log(s) //[Function: toString]函數(shù)參數(shù)的解構(gòu)賦值
function add([x, y]){ //直接解析參數(shù),相當(dāng)于傳參(x,y) return x + y; } console.log(add([1, 2])); // 3 //這里需要拆開來看 let test = [[1, 2], [3, 4]].map(([a, b]) => a + b); console.log(test) // [ 3, 7 ] [//這里只是普通的嵌套數(shù)組 [1, 2], //每個子數(shù)組元素都是一個數(shù)組 [3, 4] ].map(//對他們使用map函數(shù) //這里傳入了一個函數(shù),并且參數(shù)是自動解析參數(shù)數(shù)組的,相當(dāng)于每次處理都是一整個子數(shù)組 ([a, b]) => a + b //并且因為能夠?qū)?yīng)得到析構(gòu)模式,所以直接解析這個子數(shù)組 );函數(shù)參數(shù)的解構(gòu)的默認值
undefined就會觸發(fā)函數(shù)參數(shù)的默認值
可以當(dāng)做一個對象析構(gòu)來看,只是這個對象是被放到函數(shù)參數(shù)里面去而已
//這里是為變量x,y指定默認值 function move({x = 0, y = 0} = {}) { return [x, y]; } console.log(move({x: 3, y: 8})); // [3, 8] //參數(shù)對象的y析構(gòu)失敗,所以是0,而x成功,所以能夠使用新的值 console.log(move({x: 3})); // [3, 0] //參數(shù)對象析構(gòu)都失敗,因為是空對象 console.log(move({})); // [0, 0] //參數(shù)對象析構(gòu)都失敗,因為什么都沒有 console.log(move()); // [0, 0] //這里是為函數(shù)move的參數(shù)指定默認值,而不是為變量x和y指定默認值 function move({x, y} = { x: 0, y: 0 }) { return [x, y]; } console.log(move({x: 3, y: 8})); // [3, 8] //因為y析構(gòu)失敗,所以y是undefined,但是沒有觸發(fā)外面參數(shù)對象的undefined,所以直接返回x,y的值 console.log(move({x: 3})); // [3, undefined] //因為傳入的是空對象,也不算是undefined,沒觸發(fā)到默認值,所以直接返回x,y的值 console.log(move({})); // [undefined, undefined] //觸發(fā)到默認值了,因為什么都沒有傳,被判定為參數(shù)對象的undefined console.log(move()); // [0, 0]變量析構(gòu)的一些使用情況
交換變量的值
主要是為了簡潔,易讀
let x = 1; let y = 2; [x, y] = [y, x]; //交換變量x和y的值
從函數(shù)返回多個值
函數(shù)只能返回一個值,如果要返回多個值,只能將它們放在數(shù)組或?qū)ο罄锓祷?所以需要從里面取出來
// 返回一個數(shù)組 function example() { return [1, 2, 3]; } let [a, b, c] = example();//直接取出數(shù)組內(nèi)容,賦值到變量或者數(shù)組 console.log([a, b, c]); //[ 1, 2, 3 ] // 返回一個對象 function example1() { return { foo: 1, bar: 2 }; } let { foo, bar } = example1();//直接取出對象內(nèi)容 console.log({ foo, bar }) //{ foo: 1, bar: 2 }
函數(shù)參數(shù)的定義
解構(gòu)賦值可以方便地將一組參數(shù)與變量名對應(yīng)起來。
// 參數(shù)是一組有次序的值 function f([x, y, z]) { ... }//這個其實跟普通傳參差不多 f([1, 2, 3]); // 參數(shù)是一組無次序的值 function f({x, y, z}) { ... } //這里傳參是用對象的方式就比較方便指定對象屬性 f({z: 3, y: 2, x: 1});
提取JSON數(shù)據(jù)
解構(gòu)賦值對提取JSON對象中的數(shù)據(jù),尤其有用。
let jsonData = { id: 42, status: "OK", data: [867, 5309] }; //其實json對象也是對象,所以直接能夠解析對象的方便性也體現(xiàn)在這里 let { id, status, data: number } = jsonData; console.log(id, status, number); // 42, "OK", [867, 5309]
函數(shù)參數(shù)的默認值
指定參數(shù)的默認值,就避免了在函數(shù)體內(nèi)部再寫var foo = config.foo || "default foo";這樣的語句。
jQuery.ajax = function (url, { async = true, //默認值 beforeSend = function () {}, //默認值 cache = true, //默認值 complete = function () {}, //默認值 crossDomain = false, //默認值 global = true, //默認值 // ... more config }) { // ... do stuff };
遍歷Map結(jié)構(gòu)
任何部署了Iterator接口的對象,都可以用for...of循環(huán)遍歷。Map結(jié)構(gòu)原生支持Iterator接口,配合變量的解構(gòu)賦值,獲取鍵名和鍵值就非常方便。
var map = new Map(); //map結(jié)構(gòu) map.set("first", "hello");//map結(jié)構(gòu)的數(shù)據(jù)格式,本質(zhì)上也是key/value的hash,first是key,hello是value map.set("second", "world"); //直接解析鍵值 for (let [key, value] of map) { console.log(key + " is " + value); } // first is hello // second is world
Map 結(jié)構(gòu)提供了“值—值”的對應(yīng),是一種更完善的 Hash 結(jié)構(gòu)實現(xiàn)。參考地址
輸入模塊的指定方法
加載模塊時,往往需要指定輸入哪些方法。解構(gòu)賦值使得輸入語句非常清晰。
const { SourceMapConsumer, SourceNode } = require("source-map");
參考引用:
es6-變量的解構(gòu)賦值
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/86824.html
摘要:學(xué)習(xí)筆記頂層對象雖然是筆記但是基本是抄了一次大師的文章了頂層對象頂層對象,在瀏覽器環(huán)境指的是對象,在指的是對象。之中,頂層對象的屬性與全局變量是等價的。的寫法模塊的寫法上面代碼將頂層對象放入變量。參考引用頂層對象實戰(zhàn) es6學(xué)習(xí)筆記-頂層對象_v1.0 (雖然是筆記,但是基本是抄了一次ruan大師的文章了) 頂層對象 頂層對象,在瀏覽器環(huán)境指的是window對象,在Node指的是gl...
摘要:考慮到環(huán)境導(dǎo)致的行為差異太大,應(yīng)該避免在塊級作用域內(nèi)聲明函數(shù)。函數(shù)聲明語句函數(shù)表達式循環(huán)循環(huán)還有一個特別之處,就是循環(huán)語句部分是一個父作用域,而循環(huán)體內(nèi)部是一個單獨的子作用域。聲明一個只讀的常量。 es6學(xué)習(xí)筆記-let,const和塊級作用域_v1.0 塊級作用域 javascript 原來是沒有塊級作用域的,只有全局作用域和函數(shù)作用域 例子1 因為沒有塊級作用域,所以每次的i都是一...
摘要:因為箭頭函數(shù)本身沒有所以不可以當(dāng)作構(gòu)造函數(shù),也就是說,不可以使用命令,否則會拋出一個錯誤。箭頭函數(shù)不可以使用對象,該對象在函數(shù)體內(nèi)不存在。 es6學(xué)習(xí)筆記-箭頭函數(shù)_v1.0 箭頭函數(shù)使用方法 var f = v => v; //普通函數(shù)配合箭頭函數(shù)寫法,這里并且是傳參的 //相當(dāng)于 var f = function(v) { return v; }; /*-----------...
摘要:學(xué)習(xí)筆記字符串模板實例模板編譯先組成一個模板使用放置代碼使用輸出表達式。這被稱為標(biāo)簽?zāi)0骞δ堋T摂?shù)組的成員與數(shù)組完全一致參考引用字符串?dāng)U展 es6學(xué)習(xí)筆記-字符串模板_v1.0 實例:模板編譯 //先組成一個模板 var template = ` //使用放置JavaScript代碼 //使用輸出JavaScript表達式。 `; //這是編譯模板的函數(shù),將模...
摘要:學(xué)習(xí)筆記函數(shù)擴展函數(shù)參數(shù)的默認值如果參數(shù)默認值是變量,那么參數(shù)就不是傳值的,而是每次都重新計算默認值表達式的值。屬性函數(shù)的屬性,返回該函數(shù)的函數(shù)名。箭頭函數(shù)詳細鏈接參考引用函數(shù)擴展 es6學(xué)習(xí)筆記-函數(shù)擴展_v1.0 函數(shù)參數(shù)的默認值 function Point(x = 0, y = 0) { this.x = x; this.y = y; } var p = ne...
閱讀 1533·2021-11-23 09:51
閱讀 3646·2021-09-26 09:46
閱讀 2135·2021-09-22 10:02
閱讀 1849·2019-08-30 15:56
閱讀 3332·2019-08-30 12:51
閱讀 2235·2019-08-30 11:12
閱讀 2069·2019-08-29 13:23
閱讀 2331·2019-08-29 13:16