ES6 新增数据类型, 类似于字符串类型, 通常用来作为对象的属性名.
创建和使用
var key = Symbol();
typeof key ; // 'symbol'
var obj = {}
obj[key] = 'hello'
console.log(obj); // {Symbol():'hello'}
obj[key]; // 'hello'
var key2 = Symbol();
obj[key2] = 'world';
console.log(obj); // {Symbol(): "hello", Symbol(): "world"}
obj[key2]; // 'world'
// Symbol 可以加参数, 只是为了比较容易做区分, 非必要
var key3 = Symbol('kitty');
obj[key3] = 'hello kitty';
console.log(obj); // {Symbol(): "hello", Symbol(): "world", Symbol(kitty): "hello kitty"}
obj[key3]; // "hello kitty"
// 相同参数也是不同的值
var key4 = Symbol('kitty')
key3 == key4 ; // false
obj.a= '1'
// symbol 属性不能被 for in 遍历
for(var attr in obj){
console.log(attr); // 只有 'a'
}
// symbo 的遍历借用 Object.getOwnPropertySymbols
Object.getOwnPropertySymbols(obj).forEach(symbolKey=>{
console.log(obj[symbolKey]); //
})
应用
symbol 通过一个局部变量保存 Symbol() 的值, 然后用这个变量作为对象的一个属性名, 这样超出对象定义的作用域范围 , 拿到这个 key 值进行赋值就不是很方便, 一定程度上了保护了该属性不被更改.
function test(){
var _version = Symbol('version');
return {
name:'xx',
[_version] : '1.0.0'
}
}
var obj = test();
obj.name = 'ffff';
// 但是却不能直接操作 1.0.0 的那个值
// 通过 Symbol.for 方法查找到对应值再进行操作, 定义处和查找处都需要修改
function test2(){
var _version2 = Symbol.for('version2');
return {
name:'xx',
[_version2] : '1.0.0'
}
}
var obj2 = test2();
var versionSymbolKey = Symbol.for('version2')
obj2[versionSymbolKey] = '2.0.0'
console.log(obj2); // {name: "xx", Symbol(version2): "2.0.0"}
注意
Symbol() === Symbol() ; // false
Symbol('version') === Symbol.for('version'); // false
Symbol.for('version') === Symbol.for('version'); // true
简单部分功能模拟
仅简单模拟了 Symbol 生成key 和 Symbol.for 优先检索是否已经存在对应的参数的 key
const Symbol = function(){
var randomSymbolKey = `symbol_${Date.now()}`
return randomSymbolKey;
}
Symbol.list = {};
Symbol.for = function(key){
if(!Symbol.list[key]){
Symbol.list[key] = `symbol_${Date.now()}`
}
return Symbol.list[key]
}