一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第 21 天,点击查看活动详情。
常用内置符号
除了定义自己使用的Symbol值,ES6也提供了一批常用的内置符号,用于暴露语言内部行为。
ECMAScript 6 也引入了一批常用内置符号(well-known symbol),用于暴露语言内部行为,开发者 可以直接访问、重写或模拟这些行为。这些内置符号都以 Symbol 工厂函数字符串属性的形式存在。
内置符号最重要的用途之一是重新定义它们,从而改变原生结构的行为。
这些内置符号都是全局函数 Symbol 的普通字符串属性,指向一个符号的实例。其内置符号属性都是不可写、不可枚举、不可配置的。
1、Symbol.hasInstance
根据 ECMAScript 规范,这个符号作为一个属性表示“一个方法,该方法决定一个构造器对象是否认可一个对象是它的实例。由 instanceof 操作符使用”。
首先要知道 对象的Symbol.hasInstance属性, 指向的是一个方法;
其次,instanceof运算符知道吧,用过吧?我们知道可以使用 instanceof运算符 判断一个变量是否是某对象实例。
在 ES6 中,instanceof 操作符会使用 Symbol.hasInstance 函数来确定关系。
function Foo() {};
let f = new Foo();
console.log(f instanceof Foo); // true
console.log(Foo[Symbol.hasInstance](f)); // true
在继承的类上通过静态方法重新定义这个函数:
class EvenNum{
static [Symbol.hasInstance](obj) {
return Number(obj) % 2 === 0;
}
}
1 instanceof EvenNum // false
2 instanceof EvenNum // true
2、Symbol.isConcatSpreadable
根据 ECMAScript 规范,这个符号作为一个属性表示“一个布尔值,如果是 true,则意味着对象应 该用 Array.prototype.concat()打平其数组元素”。
首先要知道 Symbol.isConcatSpreadable 表示一个布尔值;
其次,数组的concat()方法知道吧,用过吧?连接两个或多个数组。
let arr1= ['1','2'],
arr2= ['3', '4', '5'];
let numarr = arr1.concat(arr2, '6')
console.log(numarr); // ['1', '2', '3', '4', '5', '6'];
arr1[Symbol.isConcatSpreadable] // undefined
arr1[Symbol.isConcatSpreadable] = false;
numarr = arr1.concat(arr2, '6')
console.log(numarr); // [arr1, '3', '4', '5', '6']
arr1[Symbol.isConcatSpreadable] = true;
arr2[Symbol.isConcatSpreadable] = false;
numarr = arr1.concat(arr2, '6')
console.log(numarr); // ['1', '2', Array(3), '6']
concat()方法链接数组时,默认情况下会被打平到已有的数组;
Symbol.isConcatSpreadable默认等于undefined。
如果把数组的Symbol.isConcatSpreadable设置成false; 那么连接多个数组时,这个值为false的数组会直接被追加到数组中,不会打平。
注意类数组与数组行为相反。类数组默认是追加到数组末尾,不会打平;可以为其设置为true就可以打平到数组中了。