1、解構
在接收數據的地方(比如賦值的左邊),解構使你使用模式去獲取部分數據。
下面的代碼是解構的一個例子:
let obj = { first: 'Jane', last: 'Doe' }; let { first: f, last: l } = obj; // (A)
// f = 'Jane'; l = 'Doe'
在行 A 解構了 obj
:通過左邊的模式,運用賦值操作符(=)從里面獲取數據,並將數據賦值給變量 f
和 l
。這些變量事先自動聲明好,因為該行以 let
開始。
也可以解構數組:
let [x, y] = ['a', 'b']; // x = 'a'; y = 'b'
解構可以用於下列情形:
// Variable declarations:解構賦值不僅適用於var命令,也適用於let和const命令。
let [x] = ['a']; const [x] = ['a']; var [x] = ['a']; // Assignments:
[x] = ['a']; // Parameter definitions:
function f([x]) { ··· } f(['a']);
也可以在一個 for-of
循環中解構:
// Handled like a variable declaration:
for (let [k,v] of arr.entries()) ··· // Handled like an assignment
for ({name: n, age: a} of arr) ···
(1)Rest解構賦值
對象的Rest解構賦值用於從一個對象取值,相當於將所有可遍歷的、但尚未被讀取的屬性,分配到指定的對象上面。所有的鍵和它們的值,都會拷貝到新對象上面。
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 }; x // 1 y // 2 z // { a: 3, b: 4 }
上面代碼中,變量z
是Rest解構賦值所在的對象。它獲取等號右邊的所有尚未讀取的鍵(a
和b
),將它們和它們的值拷貝過來。
由於Rest解構賦值要求等號右邊是一個對象,所以如果等號右邊是undefined
或null
,就會報錯,因為它們無法轉為對象。
let { x, y, ...z } = null; // 運行時錯誤 let { x, y, ...z } = undefined; // 運行時錯誤
Rest解構賦值必須是最后一個參數,否則會報錯。
let { ...x, y, z } = obj; // 句法錯誤 let { x, ...y, ...z } = obj; // 句法錯誤
上面代碼中,Rest解構賦值不是最后一個參數,所以會報錯。
圓括號問題
解構賦值雖然很方便,但是解析起來並不容易。對於編譯器來說,一個式子到底是模式,還是表達式,沒有辦法從一開始就知道,必須解析到(或解析不到)等號才能知道。
由此帶來的問題是,如果模式中出現圓括號怎么處理。ES6的規則是,只要有可能導致解構的歧義,就不得使用圓括號。
-
變量聲明語句中,不能帶有圓括號。
-
函數參數中,模式不能帶有圓括號。
-
賦值語句中,不能將整個模式,或嵌套模式中的一層,放在圓括號之中。
用途:
-
交換變量的值
-
從函數返回多個值
-
函數參數的定義
-
提取JSON數據
-
函數參數的默認值
-
遍歷Map結構
-
輸入模塊的指定方法
總結:
-
如果解構不成功,變量的值就等於
undefined
。 -
不完全解構,即等號左邊的模式,只匹配一部分的等號右邊的數組。這種情況下,解構依然可以成功。
-
解構賦值允許指定默認值。
-
對象的解構與數組有一個重要的不同。數組的元素是按次序排列的,變量的取值由它的位置決定;而對象的屬性沒有次序,變量必須與屬性同名,才能取到正確的值。
-
默認值生效的條件是,對象的屬性值嚴格等於
undefined
。 -
解構賦值時,如果等號右邊是數值和布爾值,則會先轉為對象。由於
undefined
和null
無法轉為對象,所以對它們進行解構賦值,都會報錯。
2、新的對象字面量特性
1、新的對象字面量特性
方法定義:
let obj = { myMethod(x, y) { ··· } };
屬性值縮寫:
let first = 'Jane'; let last = 'Doe'; let obj = { first, last }; // Same as:
let obj = { first: first, last: last };
計算屬性鍵:
let propKey = 'foo'; let obj = { [propKey]: true, ['b'+'ar']: 123 };
這種新語法也可用於方法定義:
let obj = { ['h'+'ello']() { return 'hi'; } }; console.log(obj.hello()); // hi
計算屬性鍵主要的應用場景就是使 symbol 成為屬性鍵變得更加方便。
2、Object
中的新方法
Object
中最重要的新方法是 assign()
。習慣上,在 JavaScript 的世界中,這個函數叫做 extend()
。 Object.assign()
僅考慮自有(非繼承)屬性。
let obj = { foo: 123 }; Object.assign(obj, { bar: true }); console.log(JSON.stringify(obj)); // {"foo":123,"bar":true}
常見用途:
(1)為對象添加屬性
(2)為對象添加方法
(3)克隆對象
(4)合並多個對象
(5)為屬性指定默認值
屬性的遍歷
ES6一共有6種方法可以遍歷對象的屬性。
(1)for...in
for...in
循環遍歷對象自身的和繼承的可枚舉屬性(不含Symbol屬性)。
(2)Object.keys(obj)
Object.keys
返回一個數組,包括對象自身的(不含繼承的)所有可枚舉屬性(不含Symbol屬性)。
(3)Object.getOwnPropertyNames(obj)
Object.getOwnPropertyNames
返回一個數組,包含對象自身的所有屬性(不含Symbol屬性,但是包括不可枚舉屬性)。
(4)Object.getOwnPropertySymbols(obj)
Object.getOwnPropertySymbols
返回一個數組,包含對象自身的所有Symbol屬性。
(5)Reflect.ownKeys(obj)
Reflect.ownKeys
返回一個數組,包含對象自身的所有屬性,不管是屬性名是Symbol或字符串,也不管是否可枚舉。
(6)Reflect.enumerate(obj)
Reflect.enumerate
返回一個Iterator對象,遍歷對象自身的和繼承的所有可枚舉屬性(不含Symbol屬性),與for...in
循環相同。
以上的6種方法遍歷對象的屬性,都遵守同樣的屬性遍歷的次序規則。
- 首先遍歷所有屬性名為數值的屬性,按照數字排序。
- 其次遍歷所有屬性名為字符串的屬性,按照生成時間排序。
- 最后遍歷所有屬性名為Symbol值的屬性,按照生成時間排序。
注意,語言規范把索引定義為字符串鍵,當轉換成無符號整數然后再轉換回來,仍然是同樣的字符串(同樣也必須比232-1小,因此數組是有長度限制的)。這意味着規范把數組索引看作字符串鍵,甚至普通的對象都可以有數組索引:
Reflect.ownKeys({ [Symbol()]:0, b:0, 10:0, 2:0, a:0 }) //['2', '10', 'b', 'a', Symbol()]
__proto__
屬性,Object.setPrototypeOf(),Object.getPrototypeOf()
(1)__proto__
屬性
__proto__
屬性(前后各兩個下划線),用來讀取或設置當前對象的prototype
對象。目前,所有瀏覽器(包括IE11)都部署了這個屬性。
在實現上,__proto__
調用的是Object.prototype.__proto__。
(2)Object.setPrototypeOf()
Object.setPrototypeOf
方法的作用與__proto__
相同,用來設置一個對象的prototype
對象。它是ES6正式推薦的設置原型對象的方法。
// 格式 Object.setPrototypeOf(object, prototype) // 用法 var o = Object.setPrototypeOf({}, null);
該方法等同於下面的函數。
function (obj, proto) { obj.__proto__ = proto; return obj; }
(3)Object.getPrototypeOf()
該方法與setPrototypeOf方法配套,用於讀取一個對象的prototype對象。
Object.values(),Object.entries()
Object.keys()
ES5引入了Object.keys
方法,返回一個數組,成員是參數對象自身的(不含繼承的)所有可遍歷(enumerable)屬性的鍵名。
Object.values()
Object.values
方法返回一個數組,成員是參數對象自身的(不含繼承的)所有可遍歷(enumerable)屬性的鍵值。
Object.entries
Object.entries
方法返回一個數組,成員是參數對象自身的(不含繼承的)所有可遍歷(enumerable)屬性的鍵值對數組。