@JunQiu
2018-09-18T18:20:18.000000Z
字数 2636
阅读 1289
summary_2018/07
designPattern
language_js
ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。它是JavaScript语言的第七种数据类型,前六种是:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。
Tips:Symbol 值通过Symbol函数生成,是原始数据类型,不能由new的方式生成。Symbol函数可以接受一个字符串作为参数,表示对Symbol实例的描述,主要是为了在控制台显示,或者转为字符串时,比较容易区分。
Example:
let s1 = Symbol('foo');
let s2 = Symbol('bar');
s1 // Symbol(foo)
s2 // Symbol(bar)
s1.toString() // "Symbol(foo)"
s2.toString() // "Symbol(bar)"
Tips:Symbol 值不能与其他类型的值进行运算,会报错。可以显式转换为字符串,也可以转换为bool值,但不能转换为数值。
## 作为属性名使用
在以前,只有只能为字符串,但symbol也可以作为对象的属性名。
由于每一个 Symbol 值都是不相等的,这意味着 Symbol 值可以作为标识符,用于对象的属性名,就能保证不会出现同名的属性。这对于一个对象由多个模块构成的情况非常有用,能防止某一个键被不小心改写或覆盖
Tips:Symbol值作为对象属性名时,不能用点运算符。
Example:
let mySymbol = Symbol();
// 第一种写法
let a = {};
a[mySymbol] = 'Hello!';
// 第二种写法
let a = {
[mySymbol]: 'Hello!'
};
// 第三种写法
let a = {};
Object.defineProperty(a, mySymbol, { value: 'Hello!' });
// 遍历
Symbol 作为属性名,该属性不会出现在for...in、for...of循环中,也不会被Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()返回。但是,它也不是私有属性,有一个Object.getOwnPropertySymbols方法,可以获取指定对象的所有 Symbol 属性名。
或者,使用Reflect.ownKeys方法可以返回所有类型的键名,包括常规键名和 Symbol 键名。
Tips:由于以Symbol值作为名称的属性,不会被常规方法遍历得到。我们可以利用这个特性,为对象定义一些非私有的、但又希望只用于内部的方法。
## 模块中防止模块被覆盖
const FOO_KEY = Symbol.for('foo');
// FOO_KEY的值是唯一的
module.exports = global[FOO_KEY];
## 消除魔术字符串
魔术字符串指的是,在代码之中多次出现、与代码形成强耦合的某一个具体的字符串或者数值。
风格良好的代码,应该尽量消除魔术字符串,改由含义清晰的变量代替。
如果只需要保证不冲突,可以使用Symbol类型的变量代替。
## Symbol.for(),Symbol.keyFor()
Symbol.for接受一个字符串作为参数,然后搜索有没有以该参数作为名称的 Symbol 值。如果有,就返回这个 Symbol 值,否则就新建并返回一个以该字符串为名称的 Symbol 值。(若需要重新使用一个symbol值,可以采用本方法,会被登记在全局环境中供搜索)
Symbol.keyFor方法返回一个已登记的 Symbol 类型值的key。
## ES6 还提供了11个内置的Symbol值,指向语言内部使用的方法。
Tips:如果多次执行这个脚本,每次得到的symbol都是不一样的。(虽然node有缓存,但用户可以手动清楚,不可靠)
## mix-in 对象
function minin (src, des) {
for (let k in src) {
// if you do not want cover,you can use if (!des[k)
des[k] = src[k]
}
}
let src = {
name: 'test'
}
let des = {}
minin(src, des)
console.log(des)
## mix-in 类
function minin (src, des) {
const srcPro = src.prototype
let desPro = des.prototype
for (let k in srcPro) {
if (!desPro[k]) {
desPro[k] = srcPro[k]
}
}
}
function Src () {}
Src.prototype.name = 'test'
Src.prototype.getName = function () {
console.log('111111')
}
function Des () {}
// mix-in
minin(Src, Des)
const des = new Des()
console.log(des.name)
Tips:js函数没有返回值时默认返回undefined