广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >详解JavaScript原始数据类型Symbol
  • 284
分享到

详解JavaScript原始数据类型Symbol

2024-04-02 19:04:59 284人浏览 薄情痞子
摘要

目录简介描述信息命名冲突私有属性总结简介 创建symbol变量最简单的方法是用Symbol()函数。sysmbol变量有两点比较特别: 1.它可以作为对象属性名。只有字符串和 sym

简介

创建symbol变量最简单的方法是用Symbol()函数。sysmbol变量有两点比较特别:

1.它可以作为对象属性名。只有字符串和 symbol 类型才能用作对象属性名。

2.没有两个symbol 的值是相等的。


const symbol1 = Symbol();
const symbol2 = Symbol();

symbol1 === symbol2; // false

const obj = {};
obj[symbol1] = 'Hello';
obj[symbol2] = 'World';

obj[symbol1]; // 'Hello'
obj[symbol2]; // 'World'

尽管调用Symbol()让它看起来像是对象,实际上symbol是 javascript 原始数据类型。把Symbol当作构造函数来用new会报错。


const symbol1 = Symbol();

typeof symbol1; // 'symbol'
symbol1 instanceof Object; // false

// Throws "TypeError: Symbol is not a constructor"
new Symbol();

描述信息

Symbol()函数只有一个参数,字符串description。这个字符串参数的唯一作用是辅助调试,也就是它的toString()值。但是请注意,两个具有相同description的symbol也是不相等的。


const symbol1 = Symbol('my symbol');
const symbol2 = Symbol('my symbol');

symbol1 === symbol2; // false
console.log(symbol1); // 'Symbol(my symbol)'

有一个全局的symbol注册中心,用Symbol.for()创建的symbol会添加到这个注册中心,并用它的description作为索引键。也就是说,如果你用Symbol.for()创建带有相同description的两个 symbol,它们就是相等的。


const symbol1 = Symbol.for('test');
const symbol2 = Symbol.for('test');

symbol1 === symbol2; // true
console.log(symbol1); // 'Symbol(test)'

通常来说,除非你有非常好的理由,否则不应该使用全局注册中心,因为这会造成命名冲突。

命名冲突

JavaScript 内置了一个 symbol ,那就是 es6 中的Symbol.iterator。拥有Symbol.iterator函数的对象被称为可迭代对象,就是说你可以在对象上使用for/of循环。


const fibonacci = {
  [Symbol.iterator]: function*() {
    let a = 1;
    let b = 1;
    let temp;

    yield b;

    while (true) {
      temp = a;
      a = a + b;
      b = temp;
      yield b;
    }
  }
};

// Prints every Fibonacci number less than 100
for (const x of fibonacci) {
  if (x >= 100) {
    break;
  }
  console.log(x);
}

为什么这里要用Symbol.iterator而不是字符串?假设不用Symbol.iterator,可迭代对象需要有一个字符串属性名'iterator',就像下面这个可迭代对象的类:


class MyClass {
  constructor(obj) {
    Object.assign(this, obj);
  }

  iterator() {
    const keys = Object.keys(this);
    let i = 0;
    return (function*() {
      if (i >= keys.length) {
        return;
      }
      yield keys[i++];
    })();
  }
}

MyClass的实例是可迭代对象,可以遍历对象上面的属性。但是上面的类有个潜在的缺陷,假设有个恶意用户给MyClass构造函数传了一个带有iterator属性的对象:


const obj = new MyClass({ iterator: 'not a function' });

这样你在obj上使用for/of的话,JavaScript 会抛出TypeError: obj is not iterable异常。可以看出,传入对象的iterator函数覆盖了类的iterator属性。这有点类似原型污染的安全问题,无脑复制用户数据会对一些特殊属性,比如__proto__和constructor带来问题。

这里的核心在于,symbol让对象的内部数据和用户数据井水不犯河水。由于sysmbol无法在 JSON 里表示,因此不用担心给 Express api 传入带有不合适的Symbol.iterator属性的数据。另外,对于那种混合了内置函数和用户数据的对象,比如MonGoose model,你可以用symbol来确保用户数据不会跟内置属性冲突。

私有属性

由于任何两个symbol都是不相等的,在 JavaScript 里可以很方便地用来模拟私有属性。symbol不会出现在Object.keys()的结果中,因此除非你明确地export一个symbol,或者用Object.getOwnPropertySymbols()函数获取,否则其他代码无法访问这个属性。


function getObj() {
  const symbol = Symbol('test');
  const obj = {};
  obj[symbol] = 'test';
  return obj;
}

const obj = getObj();

Object.keys(obj); // []

// 除非有这个 symbol 的引用,否则无法访问该属性
obj[Symbol('test')]; // undefined

// 用 getOwnPropertySymbols() 依然可以拿到 symbol 的引用
const [symbol] = Object.getOwnPropertySymbols(obj);
obj[symbol]; // 'test'

还有一个原因是symbol不会出现在jsON.stringify()的结果里,确切地说是JSON.stringify()会忽略symbol属性名和属性值:


const symbol = Symbol('test');
const obj = { [symbol]: 'test', test: symbol };

JSON.stringify(obj); // "{}"

总结

用 Symbol 表示对象内部状态,可以很好地隔离用户数据和程序状态。有了它,我们就不再需要某些命名约定了,比如内部属性用'$'开头。下次碰到需要定义私有属性的时候,试试Symbol类型吧!

以上就是详解JavaScript原始数据类型Symbol的详细内容,更多关于JavaScript原始数据类型Symbo的资料请关注编程网其它相关文章!

--结束END--

本文标题: 详解JavaScript原始数据类型Symbol

本文链接: https://www.lsjlt.com/news/125394.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 详解JavaScript原始数据类型Symbol
    目录简介描述信息命名冲突私有属性总结简介 创建symbol变量最简单的方法是用Symbol()函数。sysmbol变量有两点比较特别: 1.它可以作为对象属性名。只有字符串和 sym...
    99+
    2022-11-12
  • JavaScript原始数据类型Symbol的用法详解
    目录Symbol介绍与创建设置Symbol属性的注意点Symbol属性名的遍历Symbol内置值Symbol.hasInstanceSymbol.isConcatSpreadable...
    99+
    2022-11-13
    JavaScript Symbol JS Symbol
  • JavaScript新引入的原始数据类型Symbol详解
    目录SymbolSymbol转换Symbol属性名属性名遍历Symbol.for()与Symbol.keyFor()Symbol内置值Symbol.hasInstanceSymbol...
    99+
    2023-01-28
    JS Symbol JS Symbol类型
  • 详解JavaScript中原始数据类型Symbol的使用
    目录SymbolSymbol转换Symbol属性名属性名遍历Symbol.for()、Symbol.keyFor()Symbol内置值Symbol.hasInstanceSymbol...
    99+
    2023-02-22
    JavaScript原始数据类型Symbol JavaScript原始数据类型 JavaScript Symbol
  • JavaScript中原始数据类型Symbol如何使用
    本文小编为大家详细介绍“JavaScript中原始数据类型Symbol如何使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“JavaScript中原始数据类型Symbol如何使用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来...
    99+
    2023-07-05
  • JavaScript新增的两个原始数据类型详解(Record和Tuple)
    目录前言基础写法可读特性非唯一性普通对象和数组的转换支持扩展运算符JSON方法扩展提前体验应用场景总结前言 JavaScript即将推出两个新的数据类型:Record 和&...
    99+
    2022-11-13
  • JavaScript第七种数据类型Symbol的用法详解
    目录一、什么是Symbol二、作为属性名的Symbol三、Symbol中的方法1、Symbol.for()2、Symbol.keyFor()一、什么是Symbol Symbol是ES...
    99+
    2022-11-13
  • javascript七大数据类型详解
    目录前言:详细介绍:练习:总结 前言: 各大语言都会有基本类型如python,java,c系列等,基本类型的存在是不可或缺的,它就好似我们生活中算数中的整数,汉字中的中文,它就是来...
    99+
    2022-11-12
  • javascript基础之数据类型详解
    目录1.数据类型1.1 为什么需要数据类型1.2 变量的数据类型1.3 数据类型分类2. 简单数据类型(基本数据类型)2.1 数字型Number1. 数字型进制2.数字型范围2.2 ...
    99+
    2022-11-12
  • JavaScript数据类型的转换详解
    目录数据类型的转换概述强制转换Number()String()Boolean()自动转换自动转换为布尔值自动转换为字符串自动转换为数值数据类型的转换 概述 JavaScript是一种...
    99+
    2022-12-22
    JavaScript数据类型转换 JavaScript数据类型 JS 数据类型转换
  • 详解Redis数据类型实现原理
    目录1. 对象的类型与编码① type属性② encoding 属性和 *prt 指针2. 字符串对象① 编码② 编码的转换3. 列表对象① 编码② 编码转换4. 哈希对象① 编码②...
    99+
    2022-11-12
  • es6中的原始数据类型有哪些
    这篇文章主要介绍了es6中的原始数据类型有哪些的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇es6中的原始数据类型有哪些文章都会有所收获,下面我们一起来看看吧。 ...
    99+
    2022-10-19
  • JavaScript数据类型相关知识详解
    目录一、字面量1.1 数字字面量1.2 浮点数字面量1.3 特殊值1.4 字符串字面量二、变量2.1 变量的定义2.2 变量的赋值三、数据类型3.1 简单数据类型3.2 检测数据类型...
    99+
    2022-11-12
  • JavaScript数据类型转换详解(推荐)
    JS数据类型 在 JavaScript 语言中数据类型分为2大类:基本数据类型和复杂数据类型 基本数据类型有: number string boolean...
    99+
    2022-11-12
  • Javascript ES6中数据类型Symbol怎么用
    这篇文章给大家分享的是有关Javascript ES6中数据类型Symbol怎么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。介绍Symbol 是一种特殊的、不可变的数据类型,...
    99+
    2022-10-19
  • 【mysql】—— 数据类型详解
    序言: 本期我将大家认识关于 mysql 数据库中的基本数据类型的学习。通过本篇文章,我相信大家对mysql 数据类型的理解都会更加深刻。 目录 (一)数据类型分类 (二)数值类型 1、tinyint类型 2、bit类型 3、小数类型 ...
    99+
    2023-08-31
    mysql 数据库
  • SQL数据类型详解
    一、数据类型简介 数据表由多列字段构成,每一个字段指定了不同的数据类型,指定了数据类型之后,也就决定了向字段插入的数据内容; 不同的数据类型也决定了 MySQL 在存储它们的时候使用的方式,以及在使用它...
    99+
    2022-10-18
  • 详细谈谈ES6中的symbol数据类型
    目录symbol数据类型symbol出现的原因Symbol特点symbol的应用在rb对象中添加up和down方法Symbol内置的属性值总结symbol数据类型 js语言中,ES...
    99+
    2022-11-12
  • JavaScript的基础语法和数据类型详解
    目录引入JavaScript1.内部标签2.外部引入基础语法数据类型number字符串布尔值逻辑运算比较运算符数组对象流程控制Map和Setiterator总结引入JavaScrip...
    99+
    2022-11-12
  • 一起来看看JavaScript数据类型最详解
    目录01-变量的数据类型02-简单数据类型之数字型Number03-isNaN04-简单数据类型之字符串型05-转义符案例-弹出网页警示框06-字符串拼接07-字符串拼接加强08-显...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作