ES6的Symbol居然那末壮大,口试中的加分点啊

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的上下文来论述了,点击此处检察细致

《ES6的Symbol居然那末壮大,口试中的加分点啊》

作者:xiaohesong

转载链接:
https://juejin.im/post/5bdbb3…

交换:912594095、民众号:
honeyBadger8

本文转载自作者
xiaohesong 的掘金专栏

    原文作者:苏南
    原文地址: https://segmentfault.com/a/1190000017138699
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞