资讯专栏INFORMATION COLUMN

《深入理解ES6》笔记——Symbol和Symbol属性(6)

heartFollower / 1080人阅读

摘要:设置对象属性只读。提供了一个注册机制,当你注册之后,就能在全局共享注册表里面的。的注册表和对象表很像,都是结构,只不过这个是值。语法只有一个参数,返回的是从注册表获取全局共享的注意如果要防止命名重复问题,可以加上前缀。

还记得对象Object吗?

let obj = {
  a: 1
}

对象的格式:

Object {
    key: value
}

在ES5的时代,对象的key只能是字符串String类型。有人就想搞事,把key改成其他数据类型,这不是瞎折腾吗?ES组织的大神们为了对付这类搞事的人,就指定了一个新的数据类型:Symbol。

原始数据类型

学习Symbol之前,让我们回忆一下你曾经用过的原始数据类型,只有5个,别搞错了。

null、undefined

是不是面试的时候有人问过你这两者的区别?问这种问题的人很无聊,你要是和他当同事,真是受罪。

Number 数字类型

const a = 10
typeof a // number

String 字符串

const a = "haha"
typeof a // string

boolean 布尔型

const a = true, b = false
Symbol

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全局共享

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

Symbol与类型强制转换

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
Symbol检索

在对象中获取字符串的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()创建。它的使用看上面的详细介绍。

=> 返回文章目录

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/84117.html

相关文章

  • 深入理解ES6笔记(六)SymbolSymbol属性

    摘要:先搜索全局符号注册表,如果已有,则返回这个已存在的符号值否则,会创建一个新的符号值,并使用该键值将其记录到全局符号注册表中,然后返回这个新的符号值。 主要知识点:创建符号值、使用符号值、共享符号值、符号值转换。检索符号值属性以及知名符号 showImg(https://segmentfault.com/img/bVbfWhK?w=1203&h=633); 《深入理解ES6》笔记 目录 ...

    crossea 评论0 收藏0
  • 深入理解ES6笔记——迭代器(Iterator)生成器(Generator)(8)

    摘要:迭代器是一种特殊对象,每一个迭代器对象都有一个,该方法返回一个对象,包括和属性。默认情况下定义的对象是不可迭代的,但是可以通过创建迭代器。在迭代器中抛出错误不再执行生成器返回语句生成器中添加表示退出操作。迭代器是一个对象。 迭代器(Iterator) ES5实现迭代器 迭代器是什么?遇到这种新的概念,莫慌张。 迭代器是一种特殊对象,每一个迭代器对象都有一个next(),该方法返回一个对...

    AndroidTraveler 评论0 收藏0
  • 深入理解ES6笔记——Set集合与Map集合(7)

    摘要:常被用来检查对象中是否存在某个键名,集合常被用来获取已存的信息。返回一个布尔值,表示该值在中存在与否。集合存放对象的弱引用,当该对象的其他强引用被清除时,集合中的弱引用也会自动被垃圾回收机制回收,追踪成组的对象是该集合最好的使用方式。 Map和Set都叫做集合,但是他们也有所不同。Set常被用来检查对象中是否存在某个键名,Map集合常被用来获取已存的信息。 Set Set是有序列表,含...

    Charlie_Jade 评论0 收藏0

发表评论

0条评论

heartFollower

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<