JavaScript Symbol对象

Symbol

  Symbol对象是es6中新引进的一种数据类型,它的作用非常简单,就是用于防止属性名冲突而产生。

  Symbol的最大特点就是值是具有唯一性,这代表使用Symbol类型的值能做独一无二的一些事情。

  此外,Symbol没有构造函数,这使得我们不能new它,直接使用即可。

基础知识

声明Symbol


  使用Symbol()声明一个独一无二的值。

<script>

"use strict";

let Sym1 = Symbol(); // 独一无二的值
let Sym2 = Symbol();

console.log(typeof Sym1); // symbol

console.log(Sym1 == Sym2); // false

</script>

描述信息


  为Symbol的值在声明时添加一段描述信息。

  使用description属性可查看描述信息。

  注意:即使两个Symbol的描述信息是一样的也不会有什么问题,因为它仅仅是描述信息而已。

<script>

"use strict";

let Sym1 = Symbol("这是Sym1的描述信息"); // 独一无二的值
let Sym2 = Symbol("这是Sym2的描述信息");

console.log(Sym1.description); // 这是Sym1的描述信息
console.log(Sym2.description); // 这是Sym2的描述信息 </script>

Symbol.for

  使用Symbol()来创建值不会进行记录,所以无论值看起来是否一样都不会引用同一份内存地址。

  而使用Symbol.for()来创建值则会进行记录,下次再创建相同的值时会直接引用记录的内存地址。

<script>

"use strict";

let Sym1 = Symbol("测试"); // 独一无二的值
let Sym2 = Symbol("测试");

console.log(Sym1 == Sym2); // false

</script>
<script>

"use strict";

let Sym1 = Symbol.for("测试"); // 将这个值的内存地址记录,下次再创建时直接引用内存地址
let Sym2 = Symbol.for("测试");

console.log(Sym1 == Sym2); // true

</script>

Symbol.keyFor


  用于返回由Symbol.for()创建的值的描述信息。

  如果值没有描述信息则返回undefined

  当然,我们也可以使用description属性来获取描述信息,二者皆可。

<script>

"use strict";

let Sym1 = Symbol.for("测试"); // 将这个值的内存地址记录,下次再创建时直接引用内存地址
let Sym2 = Symbol.for();

console.log(Symbol.keyFor(Sym1)); // 测试
console.log(Symbol.keyFor(Sym2)); // undefined

console.log(Sym1.description); // 测试
console.log(Sym2.description); // undefined

</script>

实际应用

对象属性


  Js中的对象(键)如果直接声明就会变成String类型,这在某些程度上可能会引起对象属性冲突问题。

  对象的键最好是唯一的,Symbol类型的值无疑是最好的选择。

  当我们给想对象的键设置为Symbol类型的值的时候需要注意2点问题。

  Symbol声明和访问使用 [](变量)形式操作

  不能使用 . 语法因为 .语法是操作字符串属性的

<script>

"use strict";

let username = Symbol(); // 将这个值的内存地址记录,下次再创建时直接引用内存地址
let age = Symbol();

let dic = { // 声明时加上 [] 否则会变成String类型 --> "username"
[username]:"云崖",
[age]:18,
};

// 不能使用 . 语法获取值(属性)
console.log(dic[username]); // 云崖

console.log(dic[age]); //

</script>

对象遍历


  Symbol类型值不能被 for/infor/of 遍历操作找到。

  以下示例可以看出,找不到两个Symbol类型的键。

<script>

"use strict";

let username = Symbol(); // 将这个值的内存地址记录,下次再创建时直接引用内存地址
let age = Symbol();

let dic = { // 声明时加上 [] 否则会变成String类型 --> "username"
[username]: "云崖",
[age]: 18,
"gender": "男",
};

for (let i in dic) {
console.log(i); // gender
}

// for/of 只能遍历一个迭代对象,不能直接遍历对象。所以我们使用Object.keys(dic)将dic转换为一个迭代对象。
for (let i of Object.keys(dic)) {
console.log(i); // gender
}

</script>

  可以使用 Object.getOwnPropertySymbols 获取所有Symbol属性(键)。

  注意,这是仅仅获取Symbol的属性(键)。

<script>

"use strict";

let username = Symbol(); // 将这个值的内存地址记录,下次再创建时直接引用内存地址
let age = Symbol();

let dic = { // 声明时加上 [] 否则会变成String类型 --> "username"
[username]: "云崖",
[age]: 18,
"gender": "男",
};

for (let i in Object.getOwnPropertySymbols(dic)) {
console.log(i); // 0 1
}

// for/of 只能遍历一个迭代对象,不能直接遍历对象。所以我们使用Object.keys(dic)将dic转换为一个迭代对象。
for (let i of Object.getOwnPropertySymbols(dic)) {
console.log(i); // (2) Symbol()
}

</script>

  也可以使用 Reflect.ownKeys(obj) 获取所有属性(键)包括Symbol类型的属性。

<script>

"use strict";

let username = Symbol(); // 将这个值的内存地址记录,下次再创建时直接引用内存地址
let age = Symbol();

let dic = { // 声明时加上 [] 否则会变成String类型 --> "username"
[username]: "云崖",
[age]: 18,
"gender": "男",
};

for (let i in Reflect.ownKeys(dic)) {
console.log(i); // 0 1 2
}

console.log("*".repeat(20));

// for/of 只能遍历一个迭代对象,不能直接遍历对象。所以我们使用Object.keys(dic)将dic转换为一个迭代对象。
for (let i of Reflect.ownKeys(dic)) {
console.log(i); // gender (2) Symbol()
}

</script>

私有属性


  我们可以使用Symbol不能被for/in以及for/of访问的特性,为类制作私有属性以及提供访问接口。

<script>

"use strict";


const sex = Symbol("性别");

class User {

constructor(name, age, gender) {
this[sex] = gender; // 存入类对象中
this.name = name;
this.age = age;
}

getMsg() {
// 我们希望通过提供的API接口来让用户调出gender属性
return `姓名:${this.name},年龄:${this.age},性别:${this[sex]}`
}
}

let u1 = new User("云崖", 18, "男");

console.log(u1.getMsg()); // 只能通过接口来拿到性别 姓名:云崖,年龄:18,性别:男

// 如果循环不管是for/in还是for/of都是拿不到性别的

for (const i in u1) {
console.log(i);
// name
// age

}

</script>

JavaScript Symbol对象的更多相关文章

  1. JavaScript 复制对象

    在JavaScript这门语言中,数据类型分为两大类:基本数据类型和复杂数据类型.基本数据类型包括Number.Boolean.String.Null.String.Symbol(ES6 新增),而复 ...

  2. javaScript遍历对象、数组总结(转载)

    javaScript遍历对象.数组总结  转载来源 https://www.cnblogs.com/chenyablog/p/6477866.html 在日常工作过程中,我们对于javaScript遍 ...

  3. JavaScript原生对象及扩展

    来源于 https://segmentfault.com/a/1190000002634958 内置对象与原生对象 内置(Build-in)对象与原生(Naitve)对象的区别在于:前者总是在引擎初始 ...

  4. JavaScript 复制对象【Object.assign方法无法实现深复制】

    在JavaScript这门语言中,数据类型分为两大类:基本数据类型和复杂数据类型.基本数据类型包括Number.Boolean.String.Null.String.Symbol(ES6 新增),而复 ...

  5. JavaScript Set对象

    JavaScript Set对象 Set 用于存储任何类型的唯一值,无论是基本类型还是引用类型. 只有值没有键 严格类型检测存储,字符串数字不等同于数值型数字 存储的值具有唯一性 遍历顺序是添加的顺序 ...

  6. JavaScript 遍历对象、数组总结

    在日常工作过程中,我们对于javaScript遍历对象.数组的操作是十分的频繁的,今天抽空把经常用到的方法小结一下,方便今后参考使用!   javaScript遍历对象总结     1.使用Objec ...

  7. javascript 全局对象--w3school

    JavaScript全局对象 1.  decodeURI()解析某个编码的URI. 2.decodeURInComponent()解析一个编码的URI组件. 3.encodeURI()把字符串编码为U ...

  8. JavaScript Json对象和Json对象字符串的关系 jsonObj<->JsonString

    JavaScript Json对象和Json对象字符串的关系 jsonObj<->JsonString 如下示例: 直接写的a1就是一个Json对象,a2 就是一个Json对象字符串; 通 ...

  9. 从零构建JavaScript的对象系统

    一.正统的类与继承 类是对象的定义,而对象是类的实例(Instance).类不可直接使用,要想使用就必须在内存上生成该类的副本,这个副本就是对象. 以Java为例: public class Grou ...

随机推荐

  1. 关于延迟段创建-P1

    文章目录 1 疑问点 2 环境创建 2.1 创建用户 2.2 创建表test 2.3 查看表的段信息 2.4 延迟段创建相关参数 1 疑问点 P1页有句话说道: 在Oracle 11.2.0.3.0以 ...

  2. (私人收藏)清新文艺唯美PPT模板

    清新文艺唯美PPT模板 https://pan.baidu.com/s/12hP5pT2KfPGCgOnvp0rOIAf0dj

  3. css实现1px 像素线条_解决移动端1px线条的显示方式

    使用CSS 绘制出 1px 的边框,在移动端上渲染的效果会出现不同,部分手机发现1px 线条变胖了,这篇文章整理2种方式实现1px 像素线条. 1.利用box-shadow + transform & ...

  4. JVM零碎知识

    JVM常见XX参数 查看JVM默认值 常用基本配置参数 生产环境服务器变慢,如何诊断 生产环境CPU占用过高,如何诊断 JDK自带的JVM监控和性能分析工具 jps(虚拟机进程状况工具) jinfo( ...

  5. 脱壳实践之寻找OEP——两次内存断点法

      0x00 前言 对于加壳程序第一件事就是要找到OEP(oringinal Entry point),由于加壳的缘故,当PE文件载入OD或者其他调试软件时进入的的往往是壳程序的入口地址.所以要进行逆 ...

  6. Yii2源码分析(一):入口

    写在前面,写这些随笔是记录下自己看Yii2源码的过程,可能会有些流水账,大部分解析放在注释里说明,由于个人水平有限,有不正确的地方还望斧正. web入口文件Index.php // 定义全局的常量,Y ...

  7. Let's GO(二)

    人生苦短,Let's GO Let's GO(一) Let's GO(二) Let's GO(三) Let's GO(四) 今天我学了什么? 1. Map map:映射,使用散列表(hash)实现 m ...

  8. numpy基础用法学习

    numpy get started 导入numpy库,并查看numpy版本 import numpy as np np.__version__ '1.14.0' 一.创建ndarray 1. 使用np ...

  9. scala 数据结构(三):元组Tuple

    1 元组Tuple-元组的基本使用 基本介绍 元组也是可以理解为一个容器,可以存放各种相同或不同类型的数据. 说的简单点,就是将多个无关的数据封装为一个整体,称为元组, 最多的特点灵活,对数据没有过多 ...

  10. Scala 面向对象(二):package 包 (一) 入门

    1 Scala包的基本介绍 和Java一样,Scala中管理项目可以使用包,但Scala中的包的功能更加强大,使用也相对复杂些,下面我们学习Scala包的使用和注意事项. 2 Scala包快速入门 使 ...