變量的解構賦值

標簽: ES6


  • ES6允許按照一定模式,從數(shù)組和對象中提取值,對變量進行賦值
  • 本質上屬于“模式匹配”,只要等號兩邊模式相同异吻,左邊的變量就會被賦予相應的值

數(shù)組的解構賦值

基本用法

var [a, b, c] = [1, 2, 3]
a   // 1
b   // 2
c   // 3
  • 解構不成功,則解構不成功的變量的值為undefined
  • 不完全解構喜庞,即等號左邊的模式只匹配等號右邊數(shù)組的一部分诀浪,則解構依然成功
let [x, y] = [1, 2, 3]
x   // 1
y   // 2

對于數(shù)組解構賦值,如果等式右邊不是可遍歷結構(本身 / 轉化后的對象具備Iterator接口),將會報錯

// 報錯延都,轉化后的對象不具備Iterator接口
let [a] = 1
let [b] = false
// 報錯雷猪,對象本身不具備Iterator接口
let [c] = {}        
// 解構成功,字符串能轉換成類似數(shù)組的對象
let [d, e, f, g, h] = 'hello'

默認值

  • 解構允許指定默認值
var [x, y = 2] = [1]    // x=1晰房,y=2
  • 使用嚴格相等運算符(===)判斷一個位置是否有值求摇,僅在嚴格等于undefined時射沟,默認值生效
var [x = 1] = [undefined]   // x=1
var [y = 1] = [null]        // y=null,默認值不生效
由于`(null===undefined)`的值為false与境,所以默認值不生效验夯,`y`的值為null
  • 如果默認值為一個表達式,那么這個表達式是惰性求值的摔刁,只有用到的時候才會求值
function f() {
    console.log(123)
}
let [x = f()] = [1]     // 無輸出
  • 默認值可以引用解構賦值的其他變量挥转,但該變量必須已經聲明
let [x = 1, y = x] = []     // x=1,y=1
let [a = b, b = 1] = []     // 報錯

對象的解構賦值

基本用法

var { foo, bar } = { foo: 123, bar: 345 }
foo // 123
bar // 345
  • 數(shù)組解構共屈,變量的取值取決于它的位置
  • 對象解構,變量必須與屬性同名借宵,才能得到正確的值
var { abc } = { foo: 123, bar: 345 }
abc // undefined

對象的解構賦值實際上是以下形式的簡寫

var { foo, bar } = { foo: 123, bar: 345 }   // 簡寫
var { foo: foo, bar: bar } = { foo: 123, bar: 345 }

對象解構賦值的內部機制暇务,是先找到同名屬性怔软,然后再賦給相應的變量挡逼。
真正被賦值的是后者腻豌,而不是前者

var { foo: baz } = { foo: 123, bar: 345 }
baz // 123
foo // Error:foo is not defined

對一個已經聲明的變量解構賦值吝梅,不能將大括號 { } 寫在行首,避免 javascript 將其解析為代碼塊

var x
({ x } = { x: 1 })  // 正確寫法
{ x } = { x: 1 }    // 錯誤寫法

默認值

默認值生效的條件是做瞪,對象的屬性嚴格等于undefined

var { message: msg = 123, x } = { message: undefined, x: null }
msg     // 123
x       // null

解構嵌套結構的對象

var node = {
    loc: {
        start: {
            line: 1,
            column: 5
        }
    }
}
var { loc: { start: { line, column } } } = node
line    // 1
column  // 5
loc     // Error
start   // Error

注意:loc 和 start 是模式装蓬,不是變量牍帚,因此不會被賦值

解構對象是嵌套的對象乳蛾,而且子對象所在的父對象不存在鄙币,會報錯

var { foo: { bar } } = {}

foo為父對象蹂随,bar為子對象,foo不存在详幽,報錯
原因很簡單:foo這時為undefined浸锨,再取子屬性bar就會報錯

其他類型的解構賦值

字符串的解構賦值

字符串可以解構賦值,此時字符串被轉換成了一個類似數(shù)組的對象

let [d, e, f, g, h] = 'hello'
var { length: len } = 'hello'
len     // 5

數(shù)值和布爾值的解構賦值

解構賦值時迟郎,如果等號右邊是數(shù)值或布爾值宪肖,則先轉為對象
undefinednull無法轉為對象控乾,會報錯

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

函數(shù)參數(shù)的解構賦值

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

注意區(qū)分以下兩種情況:

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

為解構設置默認值蜕衡,當解構失敗時使用默認值
move()使用了函數(shù)默認值{}慨仿,然后解構镰吆,解構失敗跑慕,使用解構默認值

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

為函數(shù)設置默認值,僅當函數(shù)沒有傳參的時候才使用默認值
move({})傳入了空對象相赁,所以沒有使用函數(shù)默認值{}钮科,接下來是解構绵脯,解構失敗休里,由于沒有解構默認值赃承,其值為undefined

變量解構的用途

交換變量的值

[x, y] = [y, x]

從函數(shù)返回多個值

function example() {
    return [1, 2, 3]
}
var [a, b, c] = example()
function example() {
    return {
        foo: 1,
        bar: 2
    }
}
var { foo, bar } = example()

函數(shù)參數(shù)的定義

// 參數(shù)是一組有次序的值
function f([x, y, z]) {  ...  }
f([1, 2, 3])
// 參數(shù)是一組無次序值
function f({ x, y, z }) {  ...  }
f({ z: 1, y: 2, x: 3 })

提取JSON數(shù)據(jù)

var jsonData = {
    id: 1,
    is_error: false,
    result: [123, 456]
}
let { id, is_error, result } = jsonData

函數(shù)參數(shù)的默認值

jQuery.ajax = function(url, {
    async = true,
    beforeSend = function() {},
    cache = true,
    complete = function() {},
    corssDomain = false,
    global = true
    // ... more config
}) {
    // ... do stuff
}

遍歷Map結構

任何部署了 Iterator接口的對象,都可以用 for...of 循環(huán)遍歷

var map = new Map()
map.set('first', 'hello')
map.set('second', 'world')
for (let [key, value] of map) {
    console.log(key, value)
}
// first hello
// second world

輸出模塊的指定方法

const { SourceMapConsumer, SourceNode } = require("source-map")
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末瞧剖,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子抓于,更是在濱河造成了極大的恐慌做粤,老刑警劉巖捉撮,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件怕品,死亡現(xiàn)場離奇詭異,居然都是意外死亡巾遭,警方通過查閱死者的電腦和手機肉康,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進店門灼舍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吼和,“玉大人纹安,你說我怎么就攤上這事⊙艟啵” “怎么了?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長咖熟。 經常有香客問我,道長柳畔,這世上最難降的妖魔是什么馍管? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮薪韩,結果婚禮上确沸,老公的妹妹穿的比我還像新娘捌锭。我一直安慰自己,他們只是感情好罗捎,可當我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布观谦。 她就那樣靜靜地躺著,像睡著了一般桨菜。 火紅的嫁衣襯著肌膚如雪豁状。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天倒得,我揣著相機與錄音泻红,去河邊找鬼。 笑死屎暇,一個胖子當著我的面吹牛承桥,可吹牛的內容都是我干的。 我是一名探鬼主播根悼,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼凶异,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了挤巡?” 一聲冷哼從身側響起剩彬,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎矿卑,沒想到半個月后喉恋,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡母廷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年轻黑,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片琴昆。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡氓鄙,死狀恐怖,靈堂內的尸體忽然破棺而出业舍,到底是詐尸還是另有隱情抖拦,我是刑警寧澤,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布舷暮,位于F島的核電站态罪,受9級特大地震影響,放射性物質發(fā)生泄漏下面。R本人自食惡果不足惜复颈,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望诸狭。 院中可真熱鬧券膀,春花似錦君纫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至舒帮,卻和暖如春会喝,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背玩郊。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工肢执, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人译红。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓预茄,卻偏偏與公主長得像,于是被迫代替她去往敵國和親侦厚。 傳聞我的和親對象是個殘疾皇子耻陕,可洞房花燭夜當晚...
    茶點故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內容