typeof Symbol(): symbol
Javascript 一共有6种数据范例:Undefined、Null、Number、String、Object、Boolean。本日,我们先看看第七种:Symbol。
为何要发生新的范例
ES5的对象属性名都是字符串,这轻易形成属性名的争执。比方,你运用了一个他人供应的对象,但又想为这个对象增加新的要领(mixin形式),新要领的名字就有可能与现有要领发生争执。假如有一种机制,保证每一个属性的名字都是举世无双的就好了,如许就从根本上防备属性名的争执。这就是ES6引入Symbol的缘由。
可见,这个范例是供应了一个不可更新的特征,如许可以保证他人不会掩盖你的属性。下面我们来看看它的模样:
语法:Symbol([description])
let mySymbol = Symbol();
let mySymbol2 = Symbol('this is just a desction');
没有new,内里的参数只是一个形貌,这就是对这个组织器的最简朴诠释了。
现实用处
当你第一眼看到Symbol,你会在想,什么鬼,不想用。当你晓得它的特征,会让你不能不注重它。我们晓得,对象的键可以用数字或字符串,但如许的话就不能保证唯一性,当我们晓得symbol的特征,就可以拿它来做试验了。
可以作为键名:
let mySymbol = Symbol();
let obj = {};
obj[mySymbol] = 'hello';
云云简朴的一句,obj
对象就运用了mySymbol
这个symbol作为键属性,它是一个symbol,不是一个字符串。你不能用点去接见它了,相似的,for-in去罗列一个含有symbol键的对象,也不会打印出来(看例子)。既然它的作用就是保证唯一,我们就可以在这类需求下满足了。
唯一性
let a = 'hello';
let b = 'hello';
console.log( a === b); // true
let a = Symbol('hello');
let b = Symbol('hello');
console.log( a === b); // false
已有的数据范例,我们很熟悉。再来看看symbol,纵然是一样的形貌,它们也是不相同的。
举一个例子:
例1
const obj = {
[Symbol('age')] : 20,
[Symbol('name')] : 'liya',
ok: true
}
for( var i in obj) {
console.log(obj[i]);
}
运转以后,你只会获得一个true。for-in 并不能接见到symbol,想要接见,你必需用到专用的api。
例2
log.levels = {
DEBUG: Symbol('debug'),
INFO: Symbol('info'),
WARN: Symbol('warn'),
};
log(log.levels.DEBUG, 'debug message');
log(log.levels.INFO, 'info message');
咋看也没有什么Symbol的事,事实上在ES5时期,你必需如许写:
log.levels = {
DEBUG: 1,
INFO: 2,
WARN: 3,
};
如许写的害处是,值不是唯一的,某天假如被人把DEBUG的值改成了3,那你不是马上懵了。用Symbol的优点在于,你不必剖析它的值是什么,它只是一个占位符,而且唯一。
注册表
每一个symbol是唯一的,纵然两个形貌一样的symbol也不相等。symbol的弱封装机制:模块建立了几个symbol,可以在恣意对象上运用,不必忧郁与别的代码建立的属性发生争执。它只在当前的作用域见效,假如要在全局中同享,就要在全局中注册,运用Symbol.for()
去注册。
Symbol('ok');
Symbol.for('ok');
console.log(Symbol('ok') === Symbol('ok')); // false
console.log(Symbol.for('ok') === Symbol.for('ok')); // true
第一句和第二句都是建立一个Symbol,差别的是,Symbol.for不再是每次建立差别的symbol,它会从注册表中找,找到了就会返回。不管你接见频频,都不会建立新的symbol。全局的symbol可以跨域和在多个页面中运用。
末了
查了一些材料,但也不是太甚清晰,毕竟用的人还不多。期待在ES6背面可以让更多人去运用,相似Symbol这类api,人人只是瞄一眼就不再关注了,除了文档不够,更多的是设想上的题目。ES6出了有一段时间,有若干api可以深入人心,我想只要在坐的列位比较清晰。