资讯专栏INFORMATION COLUMN

ES6 Symbol - 基本使用方法

paney129 / 320人阅读

摘要:但是,前来提到的个方法都不支持属性,为了保持原有的功能,新增了一个方法来检索类型的属性接下来看一下式例以上,就是关于的基本使用方法。

ES6新增了一个基本数据类型:Symbol,至此ECMAScript的基本数据类型就有了6种:
字符串,数字,布尔,null,undefined,Symbol。
关于Symbol,我打算写2篇文章来提取一下比较重要的知识点,这篇是第一篇,主要讲Symbol的基本特性和使用场景。下一篇主要讲几个比较重要的Symbol属性。废话不多说,先进入第一篇的主题:
一:Symbol的分类和创建
Symbol有两种类型:

1: 非全局(非共享)类型的Symbol
2: 全局(共享)类型的Symbol

接下来就看看怎样创建以上两种不同的Symbol:

1: 创建非全局(非共享)类型的Symbol

所有的原始值,都有其字面形式,比如一个数字:24,一个字符串:"javaScript"。但是,Symbol没有。创建一个Symbol,必须使用Symbol函数:

let color = Symbol();

Symbol()函数也接受一个可选的参数,其为字符串类型,可以作为这个Symbol的描述:

let color = Symbol("color");    

但是,这里的描述并没有实际的用途,你也不能通过任何途径访问到它,它仅仅是用作更好地理解代码或者调试的时候给你一些context。

2: 创建全局(共享)类型的Symbol

在基于可能的需求场景,比如你想要在一个大的代码库中或者跨文件追踪一个Symbol变量,ES6提供了一个可以创建全局的(共享的)Symbol变量的方法,这些全局的Symbol存在于全局的Symbol注册表里。先来看一下创建一个全局的Symbol的方法:

let uid = Symbol.for("uid");
console.log(uid); // Symbol(uid)

全局的Symbol,需要使用到Symbol.for()方法,接受一个字符串类型的参数,这个参数作为这个Symbol的key,唯一标示,同时也作为其描述。为了更了解全局Symbol的特性,我们可以看下面一段代码:

let uid = Symbol.for("uid");
let uid2 = Symbol.for("uid");
console.log(uid === uid2); // true

上面一段代码,我们先创建了一个key为"uid"的全局Symbol,后面又创建了一个相同key的全局Symbol,最后证明这两个Symbol全等,因为当调用Symbol.for("uid")方法的行为表现为:

1: 先在全局的Symbol注册表中查找key为"uid"的Symbol,如果已经存在,就直接返回
2: 如果不存在,则创建一个新的Symbol,并用这个key在全局注册,随即返回新创建的Symbol

这里还有一个方法Symbol.keyFor()用来检测一个特定的Symbol是否已经在注册表中存在:

let uid = Symbol.for("uid");
let uid2 = Symbol.for("uid");
let uid3 = Symbol("uid3");
console.log(Symbol.keyFor(uid));// uid
console.log(Symbol.keyFor(uid2));// uid
console.log(Symbol.keyFor(uid3));// undefined 

变量uid和uid2的key都是"uid",所以"uid"既是uid也是uid2的key。但是uid3不是一个全局Symbol,所以调用Symbol.keyFor()得到的结果是undefined。

二:Symbol的使用场景

Symbol的使用场景只要有:
    1: 所有使用可计算属性名的地方
    2: Object.defineProperty()
    3: Object.defineProperties()
下面来看一个综合了以上三种使用场景的代码示例:
    let firstName = Symbol("first name");
let person = {
    [firstName]: "mike" //用在对象的可计算属性
};

// 用在Object.defineProperty()
Object.defineProperty(person, firstName, {writable: false});

//用在Object.defineProperties()
let lastName = Symbol("last name");

Object.defineProperties(person, {
    [lastName]: {
        value: "deep",
        writable: true
    }
});

三:Symbol的强制类型转换
Symbol是比较特殊的原始类型,因为其他类型没有与其逻辑等价的值,所以在某些可能会发生强制类型转换的场景,会因为二出错,需要特别注意一下。这里先看一下2个会报错的场景:

1: 将Symbol与字符串相加
2: 将Symbol进行数学运算
1: 将Symbol与字符串相加
let firstName = Symbol("first name");
let desc = firstName + "!"; //Uncaught TypeError: Cannot convert a Symbol value to a string
2: 将Symbol进行数学运算
let firstName = Symbol("first name");
let desc = firstName + 1; //Uncaught TypeError: Cannot convert a Symbol value to a number

以上两例代码都是因为Symbol无法直接强制转换为字符串类型和数字类型,从而报错。但是,在一下三种场景中,却可以把Symbol转换为字符串类型:

1: 调用console.log(symbol)时,会自动转为字符串
2: Symbol主动调用toString()方法
3: 直接调用String(symbol)方法

看一下示例:

let firstName = Symbol("first name");
let middleName = Symbol("middle name");
let lastName = Symbol("last name");

let firstNameDesc = firstName.toString();
let middleNameDesc = String(middleName);
console.log(lastName); // Symbol(last name)

使用console.log()的时候,其实是因为会默认调用toString()方法,把Symbol转换为String类型。
四:Symbol属性检索
在ES6之前,我们已经有2个检索对象属性的方法:

1: Object.keys() 返回所有可枚举的属性名
2: Object.getOwnPropertyNames() 不考虑可枚举性一律返回

ES6新增了Symbol类型,且我们现在知道了Symbol也可以被用作对象的属性名。但是,前来提到的2个方法都不支持Symbol属性,为了保持原有的功能,ES6新增了一个方法来检索Symbol类型的属性:Object.getOwnPropertySymbols()
接下来看一下式例:

let firstName = Symbol("first name");
let person = {
    [firstName]: "mike",
    "lastName": "deep"
};
console.log(Object.keys(person));//["lastName"]
console.log(Object.getOwnPropertyNames(person));//["lastName"]
console.log(Object.getOwnPropertySymbols(person));//[Symbol(first name)]

以上,就是关于Symbol的基本使用方法。

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

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

相关文章

  • 通俗易懂理解ES6 - ES6的变量类型及Iterator

    摘要:迭代器在原有的数据结构类型上新增了两种类型,我们在使用的时候还可以通过自由组合的形式使用这些结构类型达到自己想要的数据结构,这就需要一种统一的接口机制供我们调用处理不同的数据结构。 引言 万丈高楼平地起,欲练此功,必先打好基本功: ) 在了解 ES6 新增的变量类型前,我们必须先知道 JavaScript 在ES6之前,有如下六种基本数据类型:Null、Undefined、Number...

    Keven 评论0 收藏0
  • ES6时代,你真的会克隆对象吗?

    摘要:原文你真的会克隆对象吗开始之前在开始聊克隆之前,我们还是先来看看数据类型。值通过函数生成,是独一无二的。同时,中规定了对象的属性名有两种类型,一种是字符串,另一种就是类型。返回一个数组,包含对象自身的所有属性的键名。 原文:你真的会克隆对象吗 开始之前 在开始聊克隆之前,我们还是先来看看js数据类型。js的数据类型分为基本数据类型和复杂数据类型。 基本数据类型:Number、Bool...

    xiaokai 评论0 收藏0
  • ES6学习总结(一)

    摘要:可以通过调用方法将创建一个新的类型的值,这个值独一无二,不与任何值相等。还可以使可扩展,在中,表达式被标准化为构造函数的一个方法,这意味着它是可扩展的。 前端发展的太快了,快到ES6,ES7出来之后,今年已经是ES8了,但是纵然前端发展很快,我们除了马不停蹄的学习新的技术之外,也要沉下心来,好好的潜心磨砺自己,本文是整理了自己学习ES6之后相关的知识要点,寄希望于书之于笔,一来自己可以...

    _ipo 评论0 收藏0
  • es6基础0x022:Symbol

    摘要:可以使用来判断类型语法与该相关连的一个名字,可以通过这个名字获取实例。例子说明和实例化的实例不同,使用实例化的实例在全局保存,相同的两个返回的实例是一样的。 0x000 概述 Symbol是es6新的基本数据类型,所以es之后的数据类型如下: 基本数据类型: Boolean Null Undefined Number String Symbol 引用类型 Object ...

    davidac 评论0 收藏0
  • ES6 Symbol - 一些重要的Symbol属性

    摘要:是一个布尔值,用于确定当调用数组的方法时,如果传入参数是一个数组,是否需要将这个数组拍平。与其他的属性不同的是,并不默认出现在标准对象中。 ECMAScript 6 通过在原型链上定义与Symbol相关的属性来暴露语言内部逻辑,使得开发者可以对一些语言的默认行为做配置。接下来我们来看看有哪些重要的Symbol属性可供我们使用: 1: Symbol.hasInstance 一个在执行 i...

    Barrior 评论0 收藏0

发表评论

0条评论

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