【ES6复习笔记】Symbol 类型及其应用(9)
一、Symbol 简介
Symbol
是 JavaScript 中的一种基本数据类型,它表示唯一的标识符。Symbol
的主要目的是防止属性名冲突,尤其是在多个代码库或模块中共享对象时。Symbol
值可以用作对象的属性名,这样可以确保属性名是唯一的,不会与其他属性名冲突。Symbol定义的对象属性不能使用for…in循环遍历,但可以使用 Reflect.ownKeys
来获取对象的所有键名。
二、Symbol 的创建
可以使用 Symbol()
函数来创建一个新的 Symbol
值。这个函数可以接受一个可选的字符串参数,作为 Symbol
的描述。描述只是为了调试目的,不会影响 Symbol
的唯一性。
let s1 = Symbol();
console.log(s1, typeof s1); // Symbol() "symbol"let s2 = Symbol('尚硅谷');
let s2_2= Symbol('尚硅谷');
console.log(s2 === s2_2); // false// 使用 Symbol.for 定义
let s3 = Symbol.for('尚硅谷');
let s3_2 = Symbol.for('尚硅谷');
console.log(s3 === s3_2); // true
在上面的代码中,s1
、s2
和 s2_2
都是不同的 Symbol
值,尽管 s2
和 s2_2
的描述相同。
三、Symbol 的应用
1. 作为对象的属性名
Symbol
可以用作对象的属性名,这样可以确保属性名是唯一的,不会与其他属性名冲突。
let game = {name:'俄罗斯方块',up: function(){},down: function(){}
};let methods = {up: Symbol(),down: Symbol()
};game[methods.up] = function(){console.log("我可以改变形状");
}game[methods.down] = function(){console.log("我可以快速下降!!");
}console.log(game);
在上面的代码中,methods.up
和 methods.down
是两个 Symbol
值,它们被用作 game
对象的属性名。这样,即使其他代码也使用了 up
和 down
作为属性名,它们也不会冲突。
2. Symbol 内置属性
除了定义自己使用的 Symbol 值以外,ES6 还提供了 11 个内置的 Symbol 值,指向语言内部使用的方法,称为“魔术方法”,因为它们会在特定的场景下自动执行。。例如,Symbol.hasInstance
可以用来定义一个对象是否是某个类的实例,Symbol.isConcatSpreadable
可以用来控制数组的展开行为。
- Symbol.hasInstance:当其他对象使用
instanceof
运算符,判断是否为该对象的实例时,会调用这个方法。 - Symbol.isConcatSpreadable:对象的
Symbol.isConcatSpreadable
属性等于的是一个布尔值,表示该对象用于Array.prototype.concat()
时,是否可以展开。 - Symbol.species:创建衍生对象时,会使用该属性。
- Symbol.match:当执行
str.match(myObject)
时,如果该属性存在,会调用它,返回该方法的返回值。 - Symbol.replace:当该对象被
str.replace(myObject)
方法调用时,会返回该方法的返回值。 - Symbol.search:当该对象被
str.search(myObject)
方法调用时,会返回该方法的返回值。 - Symbol.split:当该对象被
str.split(myObject)
方法调用时,会返回该方法的返回值。 - Symbol.iterator:对象进行
for...of
循环时,会调用Symbol.iterator
方法,返回该对象的默认遍历器。 - Symbol.toPrimitive:该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值。
- Symbol.toStringTag:在该对象上面调用
toString
方法时,返回该方法的返回值。 - Symbol.unscopables:该对象指定了使用
with
关键字时,哪些属性会被with
环境排除。
class Person{static [Symbol.hasInstance](param){console.log(param);console.log("我被用来检测类型了");return false;}
}let o = {};console.log(o instanceof Person);const arr = [1,2,3];
const arr2 = [4,5,6];
arr2[Symbol.isConcatSpreadable] = false;
console.log(arr.concat(arr2));
在上面的代码中,Symbol.hasInstance
被用来定义 Person
类的 instanceof
操作符的行为,Symbol.isConcatSpreadable
被用来控制数组的 concat
方法的展开行为。
四、总结
Symbol
是 JavaScript 中一种非常有用的数据类型,它可以用来创建唯一的标识符,防止属性名冲突,并且可以用来定义对象的一些特殊行为。通过合理使用 Symbol
,可以使代码更加健壮和可维护。