JavaScript第七种数据类型Symbol的用法详解

 更新时间:2022年09月08日 10:30:20   作者:前端--末晨曦吖  
Symbol是ES6中引入的一种新的基本数据类型,用于表示一个独一无二的值。它是JavaScript中的第七种数据类型。本文将详细讲讲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()创建的变量

到此这篇关于JavaScript第七种数据类型Symbol的用法详解的文章就介绍到这了,更多相关JavaScript Symbol内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Node.js API详解之 zlib模块用法分析

    Node.js API详解之 zlib模块用法分析

    这篇文章主要介绍了Node.js API详解之 zlib模块用法,结合实例形式分析了Node.js API中zlib模块基本功能、函数使用方法与操作注意事项,需要的朋友可以参考下
    2020-05-05
  • jsonp跨域请求实现示例

    jsonp跨域请求实现示例

    本文主要介绍了jsonp跨域请求实现示例。具有很好的参考价值。下面跟着小编一起来看下吧
    2017-03-03
  • 基于JS实现动态跟随特效的示例代码

    基于JS实现动态跟随特效的示例代码

    这篇文章主要介绍了如何利用JavaScript实现动态跟随特效,文中的示例代码讲解详细,对我们学习JS有一定的帮助,感兴趣的小伙伴可以了解一下
    2022-06-06
  • TypeScript之调用栈的实现

    TypeScript之调用栈的实现

    这篇文章主要介绍了TypeScript之调用栈的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-12-12
  • JavaScript避免嵌套代码浅析

    JavaScript避免嵌套代码浅析

    这篇文章主要介绍了JavaScript避免嵌套代码,很多时候需要编写的逻辑本身就很恶心, 乍看之下, 堆页岩般的判定嵌套里似乎每一层都是必要的, 也只能说尽量让它看起来不那么恶心
    2023-02-02
  • 一文总结JavaScript中Promise遇到的问题

    一文总结JavaScript中Promise遇到的问题

    Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。本文将总结一下在Promise中容易遇到的一些问题,感兴趣的同学可以参考下
    2023-05-05
  • 基于javascript实现彩票随机数生成(升级版)

    基于javascript实现彩票随机数生成(升级版)

    这篇文章主要为大家详细介绍了基于javascript实现彩票随机数生成的相关资料,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-01-01
  • 浅谈JS中var,let和const的区别

    浅谈JS中var,let和const的区别

    这篇文章主要介绍了浅谈JS中var,let和const的区别,let和const是ES6新增的关键字,详细的内容介绍,具有一定的参考价值,需要的朋友可以参考一下
    2022-07-07
  • JavaScript中toLocaleString()和toString()的区别实例分析

    JavaScript中toLocaleString()和toString()的区别实例分析

    这篇文章主要介绍了JavaScript中toLocaleString()和toString()的区别,结合实例形式对比分析了toLocaleString()和toString()针对字符串、数组与日期操作过程中的区别与使用技巧,需要的朋友可以参考下
    2018-08-08
  • 通过JS来判断页面控件是否获取焦点

    通过JS来判断页面控件是否获取焦点

    本篇文章主要介绍了通过JS来判断页面控件是否获取焦点的方法。需要的朋友可以过来参考下,希望对大家有所帮助
    2014-01-01

最新评论