Symbol
ES6新增加的基本数据类型,表示独一无二。因此js的基本数据类型都包括(number,string,boolean,null,undefined,symbol)
【1】永远不相等
let s1 = Symbol();
let s2 = Symbol();
console.log(s1 === s2); // false
【2】创建是可以增加标识
一般增加
string或者number的标识。由下列可以看出s3虽然增加了{a:2}对象作为标识,但是在创建的时候也先调用了toString方法转换成了string类型,因此为了避免隐式类型转换报错我们在创建的时候传入的标识值一般传string或者number
let s1 = Symbol('GuYan');
let s2 = Symbol(1);
let s3 = Symbol({a:2});
console.log(s1); // Symbol(GuYan)
console.log(s2); // Symbol(1)
console.log(s3); // Symbol([object Object])
【3】声明的属性不可枚举
let s1 = Symbol('GuYan');
let obj = {
[s1]:1,
s1:2
}
for(let key in obj){
console.log(obj[key]); // 2
}
【4】通过特有的方法Object.getOwnPropertySymbols来获取Symbol声明的属性
在【3】中我们发现知道通过
Symbol定义的对象属性是不可枚举的,但是我们有想操作这个属性的时候就可以通过Object.getOwnPropertySymbols来获取
let s1 = Symbol('GuYan');
let obj = {
[s1]:1,
s1:2
}
console.log(Object.getOwnPropertySymbols(obj)); // [Symbol(GuYan)]
【5】Symbol.for声明
在【1】中我们知道,通过
Symbol声明的变量是永远不相等的,但是我们可能在开发过程中遇到需要两个甚至多个地方公用一个唯一的值的时候,因此就需要我们使用另一种声明方式声明。
工作原理:先判断这个变量是否已经声明,如果没有声明就创建一个这个变量,已经存在了获取这个变量的值进行赋值
let s1 = Symbol.for('GuYan'); // 没有这个变量声明一个
let s2 = Symbol.for('GuYan'); // 已经存在了,获取值进行赋值
console.log(s1 === s2) // true;
【6】Symbol.keyFor()
获取
Symbol的标识,只有通过Symbol.for()创建的变量才能通过这个方法获取
let s1 = Symbol.for('GuYan');
let s2 = Symbol('GuYan');
console.log(Symbol.keyFor(s1)); // GuYan
console.log(Symbol.keyFor(s2)); // undefined
【7】元编程(对原生js操作进行修改)
- 【7-1】
Symbol.iterator实现对象的遍历(传送门) - 【7-2】
Symbol.hasInstance实现对instanceof的修改let instance = {}; console.log({a:1} instanceof instance);// TypeError: Right-hand side of 'instanceof' is not callable ------------------------------------------------ let instance = { [Symbol.hasInstance](value){ console.log(value) // {a: 1} return 'a' in value; } } console.log({a:1} instanceof instance); // true - 【7-3】
Symbol.isConcatSpreadable数组拼接的时候是否展开let arr = [1,2,3]; console.log([].concat(arr,[4,5,6])); // [1, 2, 3, 4, 5, 6] ------------------------------------------------ let arr = [1,2,3]; arr[Symbol.isConcatSpreadable] = false; console.log([].concat(arr,[4,5,6]));//[[1, 2, 3, Symbol(Symbol.isConcatSpreadable): false],4,5,6] - 【7-4】
Symbol.match、Symbol.split、Symbol.search、Symbol.replacelet obj = {}; console.log('123'.match(obj)); // null ---------------------------------------------- let obj = { [Symbol.match](value){ console.log(value); // 123 return value.length === 3; } } console.log('123'.match(obj));// true - 【7-5】
Symbol.species衍生对象class MyArray extends Array{ constructor(...args){ super(...args) } } let v = new MyArray(1,2,3); let c = v.map(item=>item*=2); // c是v的衍生对象 console.log(v instanceof MyArray); // true console.log(v instanceof Array); // ture console.log(c instanceof MyArray); // ture console.log(c instanceof Array); // true ---------------------------------------------- class MyArray extends Array{ constructor(...args){ super(...args) } // 强制修改衍生对象的指向 static get [Symbol.species]() { // 静态属于类自己的 return Array; } } let v = new MyArray(1,2,3); let c = v.map(item=>item*=2); // c是v的衍生对象 console.log(v instanceof MyArray); // true console.log(v instanceof Array); // true console.log(c instanceof MyArray); // false console.log(c instanceof Array); // true - 【7-6】
Symbol.toPrimitive数据类型转化let obj = {}; console.log(obj + ''); // [object Object] console.log(Number(obj)); // NaN console.log(+obj); // NaN ------------------------------------------- let obj = { [Symbol.toPrimitive](type){ return 123; } } console.log(obj + ''); // '123' console.log(Number(obj)); // 123 console.log(+obj); // 123 - 【7-7】
Symbol.toStringTag修改toString方法let obj = {}; console.log(Object.prototype.toString.call(obj));//[object,Object] console.log(obj+''); // [object,Object] -------------------------------------------------------------- let obj = { [Symbol.toStringTag]:'GuYan' } console.log(Object.prototype.toString.call(obj)); // [object GuYan] console.log(obj + ''); // [object GuYan] - 【7-8】
Symbol.unscopables不在作用域中的let arr = []; console.log(arr[Symbol.unscopables]);//{copyWithin: true,entries: true,fill: true,find: true,findIndex: true,flat: true,flatMap: true,flatten: true,includes: true,keys: true,values: true} Object.keys(Array.prototype[Symbol.unscopables]);//["copyWithin", "entries", "fill", "find", "findIndex", "flat", "flatMap", "includes", "keys", "values", "flatten"] // 说明,数组有 11 个属性,会被with命令排除。 ---------------------------------------------------------------------------- class MyArry extends Array{ constructor(...args) { super(...args); } } let arr = new MyArry(); console.log(arr[Symbol.unscopables]);//{copyWithin: true,entries: true,fill: true,find: true,findIndex: true,flat: true,flatMap: true,flatten: true,includes: true,keys: true,values: true} with (arr) { console.log(find); // find is not defined } ---------------------------------------------------------------------------- class MyArry extends Array{ constructor(...args) { super(...args); } get [Symbol.unscopables]() { return {find:false}; } } let arr = new MyArry(); console.log(arr[Symbol.unscopables]); // {find:false} with (arr) { console.log(find); // [Function: find] }