JS第七种数据类型Symbol详解

点击打开视频讲解更加详细

一、什么是Symbol?

Symbol是ES6中引入的一种新的基本数据类型,用于表示一个独一无二的值。它是JavaScript中的第
七种数据类型,与undefined、null、Number(数值)、String(字符串)、Boolean(布尔值)、
Object(对象)并列。

Symbol特点:

  • Symbol的值是唯一的,用来解决命名冲突问题
  • Symbol值不能与其他数据进行运算
  • Symbol定义的对象属性不能使用for...in循环遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名

基本用法:

let a = Symbol("末晨曦吖");
console.log(a); // Symbol(末晨曦吖)
console.log(typeof a); //symbol // 相同参数 Symbol() 返回的值不相等
let b = Symbol("末晨曦吖");
console.log(a === b); //false

为什么相同参数 Symbol() 返回的值不相等???

因为使用Symbol()创建一个Symbol类型的值并赋值给a变量后,你就得到了一个在内存中独一无二的值。现在除了通过变量a,任何人在任何作用域内都无法重新创建出这个值。所以就算我们通过相同参数创建的b,结果还是不相等的。

尽管a和b都是使用Symbol()创建出来的,但是它们在内存中看起来却是这样的:

实际上,a变量拿到了内存中某块内存的唯一引用(这里所说的引用,其实就是该内存的地址)。如果不借助a变量,你不可能再得到这个地址。因此:

a !== b;  //a和b持有的是两块内存的引用

const c = a;  //手动把a里保存的地址保存在c变量中
a === c; //c和a现在指向同一块内存,因为它们保存了同样的地址

这种行为看似难以理解,但其实它与对象遵循相同的规则,如:

let a = {};
let b = {}; a !== b; //a和b各自被分配了不同的内存,因此它们保存了不同的地址 //借助变量a,变量c拿到了a指向的那个对象的地址,因此两者相等
let c = a;
a === c;

但是对于同为基本数据类型的字符串来说,它不遵循类似的规则。比如:

let a = "123";
let b = "123"; a === b; //返回true。两者在常量区引用同一个字符串

我们首先通过变量a在内存中创建了字符串“123”,然后在不借助变量a的情况下,又通过var b = "123"拿到了对“123”这个字符串的引用,两者指向内存中的同一块内存地址。

因此我们说,a无法确保别的变量无法拿到它保存的地址(前提是不通过a)。但是对于var a = Symbol()这样的语句,a变量内保存的值是唯一的,因为除了借助a变量,你永远无法得到a中保存的值。这也是Symbol的本质。

作为属性名的Symbol

let mySymbol = Symbol();
// 第一种写法
let a = {};
a[mySymbol] = 'Hello!';
// 第二种写法
let a = {
[mySymbol]: 'Hello!'
};
// 第三种写法
let a = {};
Object.defineProperty(a, mySymbol, { value: 'Hello!' });
// 以上写法都得到同样结果
a[mySymbol] // "Hello!"
注意,Symbol值作为对象属性名时,不能用点运算符。 let a = {};
let name = Symbol();
a.name = 'lili';
a[name] = 'lucy';
console.log(a.name,a[name]);//lili,lucy
Symbol值作为属性名时,该属性还是公开属性,不是私有属性。

二、Symbol中的方法

1、Symbol.for()

我们知道Symbo()创建的两个变量永远不会是相同的。那么如果我们需要重新使用同一个Symbol怎么办,总不能需要挨个去进行比较吧。还好,es6为我们提供了Symbol.for()方法。 

参数是symbol类型的描述信息,不同于Symbol(),这个而参数只能是字符串或者是undefined,若已经创建了则返回这个symbol,否则就进行创建并将这个新的symbol返回,代码如下

let name = Symbol.for("末晨曦");
let name1 = Symbol.for("末晨曦");
console.log(name === name1); // true

请注意,我们在使用创建描述信息为"末晨曦"的变量的时候,使用的是for,而不是Symbol(),倘若使用Symbol()进行首次创建,for会再次创建一次,二者不会相等,代码如下:

let name = Symbol("末晨曦");
let name1 = Symbol.for("末晨曦");
console.log(name === name1); // false

原因在于Symbol.for()会有一个登记机制,使用for只会对通过for创建的symbol进行检查,不会对Symbol()创建的进行检查。

2、Symbol.keyFor()

这个方法参数是一个通过Symbol.for()创建的symbol类型变量,返回这个symbol变量的描述信息。

let name = Symbol.for("末晨曦");
console.log(Symbol.keyFor(name)); // "末晨曦"
let name1 = Symbol("末晨曦");
console.log(Symbol.keyFor(name1)); // undefined 不能查找Symbol()创建的变量

若对您有帮助,请点击跳转B站一键三连哦!感谢支持!!!

【面试题】JS第七种数据类型Symbol详解的更多相关文章

  1. ES6 之 第七种数据类型Symbol

    概述 为了减少对象的属性名冲突,ES6引入新的原始数据类型Symbol,JS的第七种数据类型. Symbol 能够保证每个属性的名字都是独一无二,这样就能从根本上防止属性名冲突. Symbol 值能够 ...

  2. js的2种继承方式详解

    js中继承可以分为两种:对象冒充和原型链方式 一.对象冒充包括三种:临时属性方式.call()及apply()方式1.临时属性方式 复制代码代码如下: function Person(name){   ...

  3. 异步加载JS的4种方式(详解)

    方案1:$(document).ready <!DOCTYPE html> <html> <head> <script src="http://co ...

  4. 黄聪:异步加载JS的4种方式(详解)

    方案1:$(document).ready <!DOCTYPE html> <html> <head> <script src="http://co ...

  5. Symbol -- JavaScript 语言的第七种数据类型

    ES5 的对象属性名都是字符串,这容易造成属性名的冲突.比如,你使用了一个他人提供的对象,但又想为这个对象添加新的方法(mixin 模式),新方法的名字就有可能与现有方法产生冲突.如果有一种机制,保证 ...

  6. 细说 JavaScript 七种数据类型

    在 JavaScript 规范中,共定义了七种数据类型,分为 “基本类型” 和 “引用类型” 两大类,如下所示: 基本类型:String.Number.Boolean.Symbol.Undefined ...

  7. JavaScript 七种数据类型

    在 JavaScript 规范中,共定义了七种数据类型,分为 “基本类型” 和 “引用类型” 两大类,如下所示: 基本类型:String.Number.Boolean.Symbol.Undefined ...

  8. ES6学习笔记(八)第七种类型Symbol

    1.概述 ES5 的对象属性名都是字符串,这容易造成属性名的冲突.比如,你使用了一个他人提供的对象,但又想为这个对象添加新的方法(mixin 模式),新方法的名字就有可能与现有方法产生冲突.如果有一种 ...

  9. JS中的函数节流throttle详解和优化

    JS中的函数节流throttle详解和优化在前端开发中,有时会为页面绑定resize事件,或者为一个页面元素绑定拖拽事件(mousemove),这种事件有一个特点,在一个正常的操作中,有可能在一个短的 ...

随机推荐

  1. UiPath程序设计文档

    1. [RPA之家]添加数据列UiPath.Core.Activities.AddDataColumn 链接: https://pan.baidu.com/s/1RRMw4voqJru-fJSoC3W ...

  2. RPA应用场景-营业收入核对

    场景概述营业收入核对 所涉系统名称 SAP ,Excel,门店业务系统 人工操作(时间/次) 4 小时 所涉人工数量 6 操作频率每日 场景流程 1.每日13点起进入SAP查询前一日营业收入记账情况: ...

  3. VisionPro · C# · 实时取像

    VisionPro 在C#项目程序中实现实时取像方式,有两种: 1.采用界面控件  CogAcqFifoTool 进行操作,与在VisionPro软件中操作一致: 2.采用界面控件 CogRecord ...

  4. Unity-A-Star寻路算法

    最短路径 将地图存成二维数组,通过行列查找: 每一步都查找周围四个方向,或者八方向的所有点,放入开表: 是否边缘 是否障碍 是否已经在确定的路线中 计算每个方向上路径消耗,一般斜着走消耗小,收益大: ...

  5. 【python基础】第08回 流程控制 for循环

    本章内容概要 1.循环结构之 for 循环 本章内容详解 1.循环结构之for循环 1.1 语法结构 for 变量名 in 可迭代对象: #字符串 列表 字典 元组 for 循环的循环体代码 针对变量 ...

  6. map集合中对应key的value为null处理办法

    问题: Map集合中对应key的value为null,但是现在需要将这个value转为Integer类型,这个value如果不是null,那么get到的是long类型或者是Bigdecimal类型 处 ...

  7. [ARC087D] Squirrel Migration 补题记录

    题目链接 简要题意: 给你一个\(N\)个节点的树,求一个\(1\cdots N\)的排列\((p_1,p_2,\cdots p_N)\) ,使得\(\sum dist(i,p_i)\)最大. 求这样 ...

  8. MyBatis项目创建

    一.开发环境的准备 总览: mybatis搭建过程: 1.导入jar 2.创建mybatis的核心(全局)配置文件mybatis-config.xml,并配置 3.创建映射文件XxxMapper.xm ...

  9. 【小程序自动化Minium】三、元素定位- WXSS 选择器的使用

    最近更新略疲,主要是业余时间多了几个变化.比如忙活自己的模拟赛车驾舱升级.还跟朋友筹备一个小程序项目.另外早上的时间留给背单词了... 上一章中讲到Page接口的get_element()与get_e ...

  10. super详解(继承)

    //在Java中,所有的类,都默认直接或者间接继承objec类// Person 人 :父类public class Person /*extends object*/ { public Person ...