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. Vue.js 组件复用和扩展之道

    软件编程有一个重要的原则是 D.R.Y(Don't Repeat Yourself),讲的是尽量复用代码和逻辑,减少重复.组件扩展可以避免重复代码,更易于快速开发和维护.那么,扩展 Vue 组件的最佳 ...

  2. 一.5.序列化应用之服务器制造厂与型号app功能

    1.环境准备: (python36env) [vagrant@CentOS7 apps]$ django-admin startapp manufacturer (1)激活:'manufacturer ...

  3. 六.url配置

    1.Django 如何处理一个请求 (1). django 加载 ROOT_URLCONF(settings.py中配置的) 指定的模块,并寻找可用的urlpatterns变量.它是 django.c ...

  4. 阿里云centos7安装redis全过程记录

    Redis下载地址:https://redis.io/download(这个连接可能得翻墙查看,但是在centos7服务器上安装过程不需要翻墙,我查看了最新的是redis-4.0.9.tar.gz ) ...

  5. 4 个好用的 Linux 监控工具

    下面是 Linux 下 4 个日常使用率非常高的监控工具,可以帮助我们准确快速的诊断系统问题. 1. iotop 如果你想知道某些进程使用了多少你宝贵的 I/O 资源,那么就使用 iotop 吧. i ...

  6. 同一WpfApplication下简单的页面转换

    别人写的很不错的Dome...分享学习下 源文件地址 : http://pan.baidu.com/share/link?shareid=1698564707&uk=3912660076

  7. HTTPS协议详解(三):PKI 体系

    转自:https://blog.csdn.net/hherima/article/details/52469488 1.RSA身份验证的隐患    身份验证和密钥协商是TLS的基础功能,要求的前提是合 ...

  8. 这些 CSS 命名规范将省下你大把调试时间

    我听说很多开发者厌恶 CSS.而在我的经验中,这往往是由于他们并没有花时间来学习 CSS. CSS 算不上是最优美的『语言』,但迄今二十多年来,它都是美化 web 举足轻重的工具.从这点来说,也还算不 ...

  9. Codeforces 1292C Xenon's Attack on the Gangs 题解

    题目 On another floor of the A.R.C. Markland-N, the young man Simon "Xenon" Jackson, takes a ...

  10. NOIP 2016 洛谷 P2827 蚯蚓 题解

    题目传送门 展开 题目描述 本题中,我们将用符号[c]表示对c向下取整,例如:[3.0」= [3.1」=[3.9」=3.蛐蛐国最近蚯蚓成灾了!隔壁跳 蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀手 ...