还记得对象Object吗?react
let obj = { a: 1 }
对象的格式:面试
Object { key: value }
在ES5的时代,对象的key只能是字符串String类型。有人就想搞事,把key改为其余数据类型,这不是瞎折腾吗?ES组织的大神们为了对付这类搞事的人,就指定了一个新的数据类型:Symbol。segmentfault
学习Symbol以前,让咱们回忆一下你曾经用过的原始数据类型,只有5个,别搞错了。函数
null、undefined学习
是否是面试的时候有人问过你这二者的区别?问这种问题的人很无聊,你要是和他当同事,真是受罪。code
Number 数字类型对象
const a = 10 typeof a // number
String 字符串ip
const a = 'haha' typeof a // string
boolean 布尔型开发
const a = true, b = false
Symbol到底长啥样?又该怎么用呢?咱们一块儿来探索一下。文档
在MDN文档中,关于Symbol的说明是这样的:
Symbol 是一种特殊的、不可变的数据类型,能够做为对象属性的标识符使用。Symbol 对象是一个 symbol primitive data type 的隐式对象包装器。
symbol 数据类型是一个原始数据类型。
Symbol的语法格式:
Symbol([description]) //description是可选的
建立一个Symbol:
看了Symbol的描述,不知道是什么鬼?长得像个函数。
咱们开始按照语法建立一个Symbol来研究一下
const name = Symbol(); const name1 = Symbol('sym1'); console.log(name, name1) // Symbol() Symbol(sym1)
Symbol不能使用new
const name = new Symbol(); //不能够这样作。 //Symbol is not a constructor
使用Symbol:
使用Number的时候,咱们能够这样写:
const b = Number(10) // 10 //简写 const b = 10
同理,使用Symbol,咱们能够这样:
const name1 = Symbol('sym1'); // Symbol(sym1)
在全部使用可计算属性名的地方,都能使用Symbol类型。好比在对象中的key。
const name = Symbol('name'); const obj = { [name]: "haha" } console.log(obj[name]) // haha
你还可使用Object.defineProperty()和Object.defineProperties()方法。这2个方法是对象的方法,可是做为Symbol类型key,也不影响使用。
// 设置对象属性只读。 Object.defineProperty(obj, name, {writable: false})
这2个方法很是有用,在react源码中,使用了大量的只读属性的对象。如下是从react源码截取的一段代码,设置了props对象只读。可是react仍旧使用字符串做为key,并不用Symbol。
Object.defineProperty(props, 'key', { get: warnAboutAccessingKey, configurable: true });
Symbol有点特殊,在js文件中定义的Symbol,并不能在其余文件直接共享。
ES6提供了一个注册机制,当你注册Symbol以后,就能在全局共享注册表里面的Symbol。Symbol的注册表和对象表很像,都是key、value结构,只不过这个value是Symbol值。
(key, Symbol)
语法:
Symbol.for() //只有一个参数
还有一个方法是获取注册表的Symbol。
语法:
Symbol.keyFor() //只有一个参数,返回的是key
从注册表获取全局共享的Symbol
let name = Symbol.for('name'); let name1 = Symbol.for('name1'); let name2 = Symbol.for('name2'); console.log(Symbol.keyFor(name)) // name console.log(Symbol.keyFor(name1)) // name1 console.log(Symbol.keyFor(name2)) // name2
注意:若是要防止Symbol命名重复问题,能够加上前缀。如:hyy.name
JavaScript中的类型能够自动转换。好比Number转换成字符串。
let a = 1; console.log(typeof a); // number console.log(a + ' haha') // '1haha'
可是注意了,Symbol不支持这种转换。Symbol就是这么拽啊!
let a = Symbol('a'); console.log(typeof a); console.log(a + ' haha') // Cannot convert a Symbol value to a string
在对象中获取字符串的key时,可使用Object.keys()或Object.getOwnPropertyNames()方法获取key,可是使用Symbol作key是,你就只能使用ES6新增的方法来获取了。
let a = Symbol('a'); let b = Symbol('b'); let obj = { [a]: "123", [b]: 45 } const symbolsKey = Object.getOwnPropertySymbols(obj); for(let value of symbolsKey) { console.log(obj[value]) } //"123" //45
Symbol还提供了多个方法给开发者使用,咱们再也不一一研究每一个方法的用途,你想要了解全面能够查看 Symbol MDN文档
咱们只须要知道Symbol如何定义,如何在全局共享,若是在对象中替代key便可应付基本的开发需求了。
最后再回顾一下Symbol是什么:Symbol是JavaScript的原始数据类型,一个全新的数据类型,和对象、数字、字符串等彻底不同,它必须经过Symbol()建立。它的使用看上面的详细介绍。