2020-04-26 變量的解構(gòu)賦值

1、數(shù)值的解構(gòu)賦值

默認(rèn)值

解構(gòu)賦值允許指定默認(rèn)值。

let [foo = true] = [];
foo // true

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

注意,ES6 內(nèi)部使用嚴(yán)格相等運算符(===),判斷一個位置是否有值。所以,只有當(dāng)一個數(shù)組成員嚴(yán)格等于undefined,默認(rèn)值才會生效。

let [x = 1] = [undefined];
x // 1

let [x = 1] = [null];
x // null

上面代碼中,如果一個數(shù)組成員是null,默認(rèn)值就不會生效,因為null不嚴(yán)格等于undefined。

如果默認(rèn)值是一個表達(dá)式,那么這個表達(dá)式是惰性求值的,即只有在用到的時候,才會求值。

function f() {
  console.log('aaa');
}

let [x = f()] = [1];

上面代碼中,因為x能取到值,所以函數(shù)f根本不會執(zhí)行。

2、對象的解構(gòu)賦值

簡介

對象的解構(gòu)與數(shù)組有一個重要的不同。數(shù)組的元素是按次序排列的,變量的取值由它的位置決定;而對象的屬性沒有次序,變量必須與屬性同名,才能取到正確的值。

let { bar, foo } = { foo: 'aaa', bar: 'bbb' };
foo // "aaa"
bar // "bbb"

如果解構(gòu)失敗,變量的值等于undefined。

let {foo} = {bar: 'baz'};
foo // undefined

對象的解構(gòu)賦值,可以很方便地將現(xiàn)有對象的方法,賦值到某個變量。

// 例一
let { log, sin, cos } = Math;

// 例二
const { log } = console;
log('hello') // hello

上面代碼的例一將Math對象的對數(shù)、正弦、余弦三個方法,賦值到對應(yīng)的變量上,使用起來就會方便很多。例二將console.log賦值到log變量。

如果變量名與屬性名不一致,必須寫成下面這樣。

let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
baz // "aaa"

let obj = { first: 'hello', last: 'world' };
let { first: f, last: l } = obj;
f // 'hello'
l // 'world'

這實際上說明,對象的解構(gòu)賦值是下面形式的簡寫

let { foo: foo, bar: bar } = { foo: 'aaa', bar: 'bbb' };

也就是說,對象的解構(gòu)賦值的內(nèi)部機(jī)制,是先找到同名屬性,然后再賦給對應(yīng)的變量。真正被賦值的是后者,而不是前者。

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

上面代碼中,foo是匹配的模式,baz才是變量。真正被賦值的是變量baz,而不是模式foo。

默認(rèn)值
var {x = 3} = {};
x // 3

var {x, y = 5} = {x: 1};
x // 1
y // 5

var {x: y = 3} = {};
y // 3

var {x: y = 3} = {x: 5};
y // 5

var { message: msg = 'Something went wrong' } = {};
msg // "Something went wrong"

默認(rèn)值生效的條件是,對象的屬性值嚴(yán)格等于undefined。

var {x = 3} = {x: undefined};
x // 3

var {x = 3} = {x: null};
x // null

上面代碼中,屬性x等于null,因為nullundefined不嚴(yán)格相等,所以是個有效的賦值,導(dǎo)致默認(rèn)值3不會生效。

注意點

(1)如果要將一個已經(jīng)聲明的變量用于解構(gòu)賦值,必須非常小心。

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

上面代碼的寫法會報錯,因為 JavaScript 引擎會將{x}理解成一個代碼塊,從而發(fā)生語法錯誤。只有不將大括號寫在行首,避免 JavaScript 將其解釋為代碼塊,才能解決這個問題。

// 正確的寫法
let x;
({x} = {x: 1});

3、字符串的解構(gòu)賦值

字符串也可以解構(gòu)賦值。這是因為此時,字符串被轉(zhuǎn)換成了一個類似數(shù)組的對象。

const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"

類似數(shù)組的對象都有一個length屬性,因此還可以對這個屬性解構(gòu)賦值。

let {length : len} = 'hello';
len // 5

4、數(shù)值和布爾值的解構(gòu)賦值

解構(gòu)賦值時,如果等號右邊是數(shù)值和布爾值,則會先轉(zhuǎn)為對象。

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

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

上面代碼中,數(shù)值和布爾值的包裝對象都有toString屬性,因此變量s都能取到值。

解構(gòu)賦值的規(guī)則是,只要等號右邊的值不是對象或數(shù)組,就先將其轉(zhuǎn)為對象。由于undefinednull無法轉(zhuǎn)為對象,所以對它們進(jìn)行解構(gòu)賦值,都會報錯。

let { prop: x } = undefined; // TypeError
let { prop: y } = null; // TypeError

5、函數(shù)參數(shù)的解構(gòu)賦值

函數(shù)的參數(shù)也可以使用解構(gòu)賦值。

function add([x, y]){
  return x + y;
}

add([1, 2]); // 3

上面代碼中,函數(shù)add的參數(shù)表面上是一個數(shù)組,但在傳入?yún)?shù)的那一刻,數(shù)組參數(shù)就被解構(gòu)成變量xy。對于函數(shù)內(nèi)部的代碼來說,它們能感受到的參數(shù)就是xy。

函數(shù)參數(shù)的解構(gòu)也可以使用默認(rèn)值。

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]

上面代碼中,函數(shù)move的參數(shù)是一個對象,通過對這個對象進(jìn)行解構(gòu),得到變量xy的值。如果解構(gòu)失敗,xy等于默認(rèn)值。

注意,下面的寫法會得到不一樣的結(jié)果。

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]

上面代碼是為函數(shù)move的參數(shù)指定默認(rèn)值,而不是為變量xy指定默認(rèn)值,所以會得到與前一種寫法不同的結(jié)果。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.數(shù)組的解構(gòu)賦值 2.對象的解構(gòu)賦值 3.字符串的解構(gòu)賦值 4.數(shù)值和布爾值的解構(gòu)賦值 5.函數(shù)參數(shù)的解構(gòu)賦值 ...
    卞卞村長L閱讀 952評論 0 0
  • 本文通過學(xué)習(xí)阮一峰的博客,外加自己的理解,整理了一下我對js變量的解構(gòu)賦值的理解。 數(shù)組的解構(gòu)賦值 對象的解構(gòu)賦值...
    宋樂怡閱讀 592評論 0 2
  • 數(shù)組的解構(gòu)賦值 對象的解構(gòu)賦值 字符串的解構(gòu)賦值 數(shù)值和布爾值的解構(gòu)賦值 函數(shù)參數(shù)的解構(gòu)賦值 圓括號問題 用途 數(shù)...
    皇甫貝閱讀 402評論 0 0
  • 數(shù)組的解構(gòu)賦值 基本用法 ES6允許按照一定模式,從數(shù)組和對象中提取值,對變量進(jìn)行賦值,這被稱為解構(gòu)(Destru...
    呼呼哥閱讀 472評論 0 3
  • 關(guān)于作者 一個生于千禧年六月的雙子,理工男中浪漫的異端。 風(fēng)象星座賦予其敏感的筆觸和細(xì)膩的情感,文風(fēng)多變,情節(jié)詭譎...
    小雪大寒閱讀 406評論 0 1

友情鏈接更多精彩內(nèi)容