Symbol基本使用
ES6 引入了一种新的原始数据类型Symbol
,表示独一无二的值。它是 JavaScript 语言的第七种数据类型,前六种是:undefined
、null
、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。
Symbol特点
- Symbol的值是唯一的,用来解决命名冲突的问题
- Symbol值不能与其他数据进行运算
- Symbol定义的对象属性不能使用for...in循环遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名
//创建Symbol
let s= Symbol();
console.log(s,typeof s);//Symbol() "symbol"
let s2 = Symbol('Study');
let s3 = Symbol('Study');
console.log(s2 === s3);//false;
//Symbol.for 创建
let s4 = Symbol.for('Study');
let s5 = Symbol.for('Study');
console.log(s4,typeof s4);//Symbol('Study') "symbol"
console.log(s4 === s5);//true;
//不能与其他数据进行运算
//let result = s + 100;
//let result = s > 100;
//let result = s + s;
七种数据类型
USONB //记忆点you are so niubility
u undefined
s string symbol
o object
n null number
b boolean
Symbol创建对象属性
//面向对象中添加方法 up down
let game = {
}
//声明一个对象
let methods = {
up:Symbol(),
dowm:Symbol()
};
game[methods.up] = function(){
console.log("我可以上升");
}
game[methods.down] = function(){
console.log("我可以下降");
}
console.log(game);//出现up,down对象
let youxi = {
name:'狼人杀',
[Symbol('say')]:function(){
console.log('我可以发言')
},
[Symbol('zibao')]:function(){
console.log('我可以自爆')
}
}
Symbol内置值
Symbol.hasInstance
// Symbol.hasInstance
class MyClass {
[Symbol.hasInstance] (foo) {
return foo instanceof Array;
}
}
[1, 2, 3] instanceof new MyClass() // true
// symbol.hasInstance:会在[1, 2, 3] instanceof 时 自动调用 [Symbol.hasInstance] (foo) 方法...
// 等价于. ([1,2,3]) => { return [1,2,3] instanceof Array}
Symbol.isConcatSpreadable
class A1 extends Array {
construcor(args) {
super(args);
this[Symbol.isConcatSpreadable] = true;
}
}
class A2 extends Array {
constructor(args) {
super(args);
this[Symbol.isConcatSpreadable] = 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]]
// Symbol.isConcatSpreadable:表示对象使用Array.prototype.concat()时,是否可以展开
Symbol.species
// Symbol.species
// 使用格式
class MyArray extends Array {
// 覆盖父类 Array 的构造函数
static get [Symbol.species] () { return Array; }
}
// 实例.
class MyArray extends Array {
static get [Symbol.species] () { return Array; }
}
var a = new MyArray(1,2,3);
var mapped = a.map (x => x * x);
mapped instanceof MyArray // false
mapped instanceof Array // true
// 注:在static get[Symbol.species] () 中 将构造函数改为了 返回Array类,, 故使用instance MyArray 返回 false.
Symbol.match
// Symbol.match
class MyMatcher {
[Symbol.match] (string) {
return 'hello world'.indexOf(string);
}
}
'e'.match(new MyMatcher)) // 1
// 注:等同于 [Symbol.match] ('e') { return 'hello world'.indexOf('e')}
Symbol.replace
// Symbol.replace
const x= {};
x[Symbol.replace] = (...s) => console.log(s);
'Hello'.replace(x, 'World')
// 注:在执行'Hello'.replace操作时,实际上执行:(['Hello','World']) => console.log ('["Hello","World"]');
// Symbol.replace会在执行String.prototype.replace方法时调用函数.
Symbol.search
// Symbol.search
class MySearch {
constructor (value) {
this.value = value;
}
[Symbol.search] (string) {
return string.indexOf(this.value);
}
}
'foobar'.search(new MySearch('foo')) // 0
// 注: [Symbol.search] (string),在执行String.prototype.search方法时调用.
// 本例相当于执行: ('foobar') { return 'foobar'.indexOf('foo')}
}
Symbol.split
// Symbol.split
class MySplitter {
constructor (value) {
this.value = value;
}
[Symbol.split] (string) {
var index = string.indexOf(this.value);
if (index = -1){
return string;
}
return [
string.substr(0, index),
string.substr(index + this.value.length)
];
}
}
'foobar'.split(new MySplitter('foo')) // ['', 'bar']
'foobar'.split(new MySplitter('bar')) // ['foo', '']
'foobar'.split(new MySplitter('baz')) // ['foobar']
// 注: [Symbol.split]](string) 在执行String.prototypr.string方法时触发
// 本例改写了split方法,将string分为2部分,一部分(未匹配的)不变,另一部分(匹配到的)置为空, 若string中无匹配值,则完整返回...
Symbol.iterator
// Symbol.iterator
class Collection {
*[Symbol.iterator] () {
let i = 0;
while (this[i] !== undefined) {
yield this[i];
++i;
}
}
}
let myCollection = new Collection();
myCollection[0] = 1;
myCollection[1] = 2;
for (let value of myCollection) {
console.log (value);
}
// 1
// 2
// 注:在执行for ... of 循环时 触发Symbol.iterator方法
// yield 在for循环时会保存当前的元素...
Symbol.toPrimitive
// Symbol.toPrimitive
let obj = {
[Symbol.toPrimitive] (hint) {
swtich (hint) {
case 'number':
return 123;
case 'string':
return 'str';
case 'default':
return ‘default';
default:
throw new Error ();
}
}
}
2 * obj ; // 246
3 + obj ; // '3default'
obj == 'default' // true
String(obj) // 'str'
// 注:在对象被转为原始类型的值时,会调用这个方法
Symbol.toStringTag
// Symbol.toStringTag
class Collection {
get [Symbol.toStringTag] () {
return 'xxx',
}
}
var x = new Collection();
Object.prototype.toString.call(x); // "[object xxx]"
// 注:当执行Object.prototype.toString方法时,触发Symbol.toStringTag
Symbol.unscopables
// Symbol.unscopables
// 无unscopables
class MyClass {
foo() { return 1;}
}
var foo = function () { return 2;};
with (MyClass.prototype) {
foo(); // 1
}
// 有unscopables
class MyClass {
foo() { return 1; }
get [Symbol.unscopables] () {
return { foo: true};
}
}
var foo = function () { return 2;};
with (MyClass.prototype) {
foo(); // 2
}
// 注:unscopables属性指定了使用with关键字时哪些属性会被with环境排除.
// 在本例中指定了foo属性被排除....