symbol是es6出的一种范例,他也是属于原始范例的领域(string, number, boolean, null, undefined, symbol)
basic
let name = Symbol('xiaohesong')
typeof name // 'symbol'
let obj = {}
obj[name] = 'xhs'
console.log(obj[name]) //xhs
symbol for
这个东西是可同享,在建立的时刻会搜检全局是不是寻在这个key的symbol.假如存在就直接返回这个symbol,假如不存在就会建立,并且在全局注册。
let uid = Symbol.for("uid");
let object = {
[uid]: "12345"
};
console.log(object[uid]); // "12345"
console.log(uid); // "Symbol(uid)"
let uid2 = Symbol.for("uid");
console.log(uid === uid2); // true
console.log(object[uid2]); // "12345"
console.log(uid2); // "Symbol(uid)"
此处所说的同享是全局性的同享,类似于global scope,是全部大环境下的同享.
symbol keyfor
let uid = Symbol.for("uid");
console.log(Symbol.keyFor(uid)); // "uid"
let uid2 = Symbol.for("uid");
console.log(Symbol.keyFor(uid2)); // "uid"
let uid3 = Symbol("uid");
console.log(Symbol.keyFor(uid3)); // undefined
全局注册表不存在uid3这个同享的symbol.所以取不出对应的key.因而可知,这个是猎取对应的key.
symbol 不可强迫转换
let uid = Symbol('uid')
uid + ''
这里会报错,依据范例,他会把uid转换成字符串举行相加。假如真的相加,能够先String(uid)以后再相加,不过现在看来,好像没什么意义。
obj中symbol key的猎取
let uid = Symbol('uid')
let obj = {
[uid]: 'uid'
}
console.log(Object.keys(obj)) // []
console.log(Object.getOwnPropertyNames(obj)) // []
console.log(Object.getOwnPropertySymbols(obj)) // [Symbol(uid)]
es6针对这个,添加了Object.getOwnPropertySymbols要领。
是不是是觉得很少用到Symbols.实在es6内部用的照样不少的。
Symbol.hasInstance
每一个函数都有这个要领。也许你对这个要领不是很熟,他实在就是instanceof所做的事变。 没错,es6给你重写了这个要领。
function Xiao(){}
const xiao = new Xiao
xiao instanceof Xiao // true
实际上es6帮你那末干了
Xiao[Symbol.hasInstance](xiao)
这个是内部的要领,不支持重写,固然,我们能够在原型上改写。
Object.definePrototype(Xiao, Symbol.hasInstance, {
value: (v) : Boolean(v)
})
const x = new Xiao
x instanceof Xiao //true
0 instanceof Xiao //false
1 instanceof Xiao //true
能够发明,我们改写他返回对应的是不是为boolean范例。
Symbol.isConcatSpreadable
这个和其他的一些属性差别,他是默许不存在一些规范对象上。简朴的运用
let objs = {0: 'first', 1: 'second', length: 2, [Symbol.isConcatSpreadable]: true}
['arrs'].concat(objs) //["arrs", "first", "second"]
Symbol.toPrimitive
这个用的就多了,举行范例转换的时刻,对象会举行尝试转换成原始范例,就是经由过程toPrimitive
.这个要领,规范范例的原型上都存在。
举行范例转换的时刻,toPrimitive
会被强迫的挪用一个参数,在范例中这个参数被称之为hint
. 这个参数是三个值(‘number’, ‘string’, ‘default’)个中的一个。
望文生义,string
返回的是string
, number
返回的是number
,default是没有迥殊指定,默许。
那末什么是默许的状况呢? 大多数的状况下,默许状况就是数字形式。(日期除外,他的默许状况视为字符串形式)
实在在范例转换时挪用默许状况的也不是许多。如(==
, +
)或许将参数传递给Date
的组织参数的时刻。
- number mode 在数字状况下的行动(优先级从高到低)
- 起首挪用valueOf,假如是一个原始范例,那就返回。
- 假如前面不是原始值,那末就尝试挪用toString,假如是原始值,那末就返回
- 假如都不存在,那末就报错
- string mode 在字符串的状况下,行动略有差别(优先级从高到低)
- 起首挪用toString,假如是原始值,那末就返回
- 假如前面不是原始值,那末就尝试挪用valueOf,假如是原始值,那末就返回
- 抛出毛病
嗯,是不是是觉得挺绕的,是啊,代码论述下嘛。
let obj = {
valueOf: function(){console.log('valueOf')},
toString: function(){console.log('toString')}
}
// console.log value is
obj + 2 //valueOf
obj == 2 // valueOf
Number(obj) // valueOf
String(obj) // toString
经由过程上面的输出,能够发明大多数的状况都是起首挪用valueOf.
包含默许的状况,他的默许是挪用的数字形式,而且绝大数都是挪用的数字形式,能够发明toString是挪用了string的形式。所以你能够以为,基础就是数字形式,除非很显现的是字符串形式。
关于这个挪用的形式还不是很清晰?没事,es6把这个内部的要领对外暴露出来了,我们能够改写他,输出这个hint的范例。 来
function Temperature(degrees) {
this.degrees = degrees;
}
Temperature.prototype[Symbol.toPrimitive] = function(hint) {
console.log('hint is', hint)
};
let freezing = new Temperature(32);
freezing + 2 // ..
freezing / 2 // ..
...
上面的范例,你能够尝尝。
Symbo.species
这个须要联络class
的上下文来论述了,点击此处检察细致
作者:xiaohesong
转载链接:
https://juejin.im/post/5bdbb3…交换:912594095、民众号:
honeyBadger8
本文转载自作者
xiaohesong
的掘金专栏