簡介
對象的 Symbol.isConcatSpreadable 屬性等于一個布爾值,表示該對象用于 Array.prototype.concat() 時,是否可以展開。詳解見 阮一峰的ES6教程。
let arr1 = ['c', 'd'];
['a', 'b'].concat(arr1, 'e') // ['a', 'b', 'c', 'd', 'e']
arr1[Symbol.isConcatSpreadable] // undefined
let arr2 = ['c', 'd'];
arr2[Symbol.isConcatSpreadable] = false;
['a', 'b'].concat(arr2, 'e') // ['a', 'b', ['c','d'], 'e']
上面代碼說明,數(shù)組的默認(rèn)行為是可以展開,Symbol.isConcatSpreadable 默認(rèn)等于 undefined。該屬性等于 true 時,也有展開的效果。
類似數(shù)組的對象正好相反,默認(rèn)不展開。它的 Symbol.isConcatSpreadable 屬性設(shè)為 true,才可以展開。
let obj = {length: 2, 0: 'c', 1: 'd'};
['a', 'b'].concat(obj, 'e') // ['a', 'b', obj, 'e']
obj[Symbol.isConcatSpreadable] = true;
['a', 'b'].concat(obj, 'e') // ['a', 'b', 'c', 'd', 'e']
Symbol.isConcatSpreadable 屬性也可以定義在類里面。
class A1 extends Array {
constructor(args) {
super(args);
this[Symbol.isConcatSpreadable] = true;
}
}
class A2 extends Array {
constructor(args) {
super(args);
}
get [Symbol.isConcatSpreadable] () {
return false;
}
}
let a1 = new A1();
a1[0] = 3;
a1[1] = 4;
let a2 = new A2();
a2[0] = 5;
a2[1] = 6;
[1, 2].concat(a1).concat(a2)
// [1, 2, 3, 4, [5, 6]]
上面代碼中,類A1是可展開的,類A2是不可展開的,所以使用concat時有不一樣的結(jié)果。
注意,
Symbol.isConcatSpreadable的位置差異,A1是定義在實例上,A2是定義在類本身,效果相同。