你需要知道的Symbols

需要,知道,symbols · 浏览次数 : 141

小编点评

**著名symbol** 是 JavaScript 中一些与其他 symbol 相似的名称,用于描述不同的 JavaScript 对象属性或方法的行为。以下是一些常见的 symbol: * **Symbol.iteratorSymbol.toStringTagSymbol.toPrimitiveSymbol.asyncIteratorSymbol.hasInstanceSymbol.isConcatSpreadableSymbol.speciesSymbol.matchSymbol.matchallSymbol.replaceSymbol.searchSymbol.splitSymbol.unscopablesSymbol.dispose**:用于定义对象迭代器,并提供一些与 `for-of`循环相关的方法。 * **Symbol.toStringTagSymbol.toStringTag**:用于指定对象的字符串表示形式。 * **Symbol.toPrimitiveSymbol.toPrimitive**:用于指定对象在隐式调用 `valueOf` 和 `toString` 方法时的行为。 * **Symbol.asyncIteratorSymbol.asyncIterator**:用于定义异步迭代器。 * **Symbol.hasInstanceSymbol.hasInstance**:用于确认一个对象是否是构造函数的实例。 * **Symbol.speciesSymbol.species**:用于指定创建派生对象时要使用的构造函数。 * **Symbol.matchSymbol.match**:用于在使用 String.prototype.match 方法时确定要搜索的值。 * **Symbol.replaceSymbol.replace**:用于在使用 String.prototype.replace 方法时确定替换值。 * **Symbol.splitSymbol.split**:用于在使用 String.prototype.split 方法时确定分隔值。 * **Symbol.unscopablesSymbol.unscopables**:用于确定应该从 `with` 语句的作用域中排除哪些对象属性。

正文

著名symbol

著名symbol是一个在不同领域中都相同且未注册的symbol。如果我们要列出著名symbol,它们会是:

  • Symbol.iterator
  • Symbol.toStringTag
  • Symbol.toPrimitive
  • Symbol.asyncIterator
  • Symbol.hasInstance
  • Symbol.isConcatSpreadable
  • Symbol.species
  • Symbol.match
  • Symbol.matchall
  • Symbol.replace
  • Symbol.search
  • Symbol.split
  • Symbol.unscopables
  • Symbol.dispose

让我们看一些例子来了解其有用性。

Symbol.iterator

Symbol.iterator:该symbol被用来为对象定义默认的迭代器。它被用来在for-of循环中实现对对象的迭代,或用于扩展操作符。

const obj = { a: 1, b: 2, c: 3 };

obj[Symbol.iterator] = function*() {
  for (const key of Object.keys(this)) {
    yield [key, this[key]];
  }
};

for (const [key, value] of obj) {
  console.log(`${key}: ${value}`);
}

Symbol.toStringTag

Symbol.toStringTag:该symbol被用来指定在调用Object.prototype.toString方法时返回的字符串值,以便为对象提供自定义的字符串表示形式。

class MyClass {
  static [Symbol.toStringTag] = 'MyClass';
}

const myInstance = new MyClass();

console.log(myInstance.toString()); // outputs '[object MyClass]'

Symbol.toPrimitive

Symbol.toPrimitive:该symbol被用来指定对象在隐式调用valueOftoString方法时的行为。可以用它来为对象提供自定义的字符串和数字表示形式。

class Life {
  valueOf() {
    return 42;
  }

  [Symbol.toPrimitive](hint) {
    switch (hint) {
      case "number":
        return this.valueOf();
      case "string":
        return "Forty Two";
      case "default":
        return true;
    }
  }
}

const myLife = new Life();
console.log(+myLife); // 42
console.log(`${myLife}`); // "Forty Two"
console.log(myLife + 0); // 42

Symbol.asyncIterator

Symbol.asyncIterator:该symbol被用来为对象定义一个异步的迭代器。可以用它来为对象启用异步迭代。

class MyAsyncIterable {
  async *[Symbol.asyncIterator]() {
    for (let i = 0; i < 5; i++) {
      await new Promise(resolve => setTimeout(resolve, 1000));
      yield i;
    }
  }
}

(async () => {
  for await (const value of new MyAsyncIterable()) {
    console.log(value);
  }
})();

// Output after one second:
// 0
// Output after two seconds:
// 1
// Output after three seconds:
// 2
// Output after four seconds:
// 3
// Output after five seconds:
// 4

Symbol.hasInstance

Symbol.hasInstance:该symbol被用来确认一个对象是否是构造函数的实例。它可以用来更改instanceof操作符的行为。

class MyArray {
  static [Symbol.hasInstance](instance) {
    return Array.isArray(instance);
  }
}

const arr = [1, 2, 3];
console.log(arr instanceof MyArray); // true

Symbol.isConcatSpreadable

Symbol.isConcatSpreadable:该symbol被用来确定对象在与其他对象连接时是否应该被展开。它可以用来更改Array.prototype.concat方法的行为。

const arr1 = [1, 2, 3];
const spreadable = { [Symbol.isConcatSpreadable]: true, 0: 4, 1: 5, 2: 6, length: 3 };

console.log([].concat(arr1, spreadable)); // [1, 2, 3, 4, 5, 6]

Symbol.species

Symbol.species:该symbol被用来指定创建派生对象时要使用的构造函数。它可以用来自定义创建新对象的内置方法的行为。

class MyArray extends Array {
  static get [Symbol.species]() {
    return Array;
  }
}

const myArray = new MyArray(1, 2, 3);
const mappedArray = myArray.map(x => x * 2);

console.log(mappedArray instanceof MyArray); // false
console.log(mappedArray instanceof Array); // true

P.S:这一功能在未来可能会被删除。

Symbol.match

Symbol.match:该symbol被用来在使用String.prototype.match方法时确定要搜索的值。它可以用来更改类似于RegExp对象的match方法的行为。

const myRegex = /test/;
'/test/'.startsWith(myRegex); // Throws TypeError

const re = /foo/;
re[Symbol.match] = false;
"/foo/".startsWith(re); // true
"/bar/".endsWith(re); // false

P.S: 这个symbol的存在是标志着一个对象是"regex"的原因。

const myRegex = /foo/g;
const str = 'How many foos in the the foo foo bar?';

for (result of myRegex[Symbol.matchAll](str)) {
  console.log(result); // we will get the matches
}

Symbol.replace

Symbol.replace:该symbol被用来在使用String.prototype.replace方法时确定替换值。它可以用来更改类似于RegExp对象的replace方法的行为。

const customReplace = str => str.replace(/\d+/g, match => `-${match}-`);

const customString = {
  [Symbol.replace]: customReplace
};

const originalString = "foo123bar456baz";

const result = originalString.replace(customString, '*');

console.log(result); // outputs "foo-123-bar-456-baz"

Symbol.split

Symbol.split:该symbol被用来在使用String.prototype.split方法时确定分隔值。它可以用来更改类似于RegExp对象的split方法的行为。

const { Symbol } = require('es6-symbol');

const customSplit = str => str.split(/\d+/);

const customRegExp = {
  [Symbol.split]: customSplit
};

const string = "foo123bar456baz";

string.split(customRegExp); // outputs [ 'foo', 'bar', 'baz' ]

Symbol.unscopables

Symbol.unscopables:该symbol被用于确定应该从with语句的作用域中排除哪些对象属性。它可以用来更改with语句的行为。

const person = {
  age: 42
};

person[Symbol.unscopables] = {
  age: true
};

with (person) {
  console.log(age);
  // Expected output: Error: age is not defined
}

Symbol.dispose

Symbol.dispose:“显式资源管理”是指用户通过使用命令式方法(如Symbol.dispose)或声明式方法(如使用块作用域声明)显式地管理“资源”的生命周期的系统。

{ 
  console.log(1); 
  using { 
    [Symbol.dispose]() { 
      console.log(2); 
     } 
  }; 
  console.log(3); 
}
// will log 1, 3, 2

总结

这篇信息性的博客旨在深入介绍JavaScript语言中固有的著名symbol,例如Symbol.iteratorSymbol.toStringTagSymbol.for。这些symbol代表着复杂而多才多艺的工具,可以用来增强和调节代码的行为。在JavaScript环境中全面理解可用symbol是开发高性能、可维护和可扩展应用程序的关键。因此,在项目的概念化和实施阶段,建议评估将这些symbol纳入其中的可行性,以使代码更加简洁、优雅,达到预期的效果。

以上就是本文的全部内容,如果对你有所帮助,欢迎收藏、点赞、转发~

与你需要知道的Symbols相似的内容:

你需要知道的Symbols

著名symbol 著名symbol是一个在不同领域中都相同且未注册的symbol。如果我们要列出著名symbol,它们会是: Symbol.iterator Symbol.toStringTag Symbol.toPrimitive Symbol.asyncIterator Symbol.hasIn

Vue vs React:你需要知道的一切

Vue 和 React 是创建 JavaScript 网络应用程序最常用的两种工具。但我们该如何在两者之间做出选择呢?在本篇 Vue 与 React 的对比中,我们将尝试找出答案。我们将回顾每种工具的优缺点,提供选择使用哪种工具的技巧,并帮助你开始使用。 总览 什么是Vue? Vue趣事 什么是Re

Grafana 系列文章(十一):Loki 中的标签如何使日志查询更快更方便

👉️URL: https://grafana.com/blog/2020/04/21/how-labels-in-loki-can-make-log-queries-faster-and-easier/ 📝Description: 关于标签在 Loki 中如何真正发挥作用,你需要知道的一切。它可

[转帖]Kafka需要知道的一些基础知识点

`https://blog.csdn.net/daima_caigou/article/details/109101405` 前言 kafka是常用MQ的一种,站在使用者的角度来看待,kafka以及所有的MQ应该是这样的: (注意箭头的方向) 这个一点问题都没有,即使你站在MQ的开发者的角度,这个图

[转帖]本周话题:真实方位是如何暴露的?

https://www.ruanyifeng.com/blog/2022/12/weekly-issue-237.html 很多时候,开发者需要知道用户的地理方位。 最简单的方法,就是查看用户的 IP 地址,它能够确定地理方位。 如果你不想暴露真实方位,需要使用技术手段,伪装自己的 IP 地址。 但

Python: 你所不知道的星号 * 用法

平常对于星号的应用场景用得少是不需要了解太多用法的。不过,学编程的过程少不了要去阅读优秀的源代码库,也就时常会对星号 * 的贸然出现和用途感到困惑,所以今天就让你们好好了解一下会有哪些用法。

我面试失败了,因为我不知道这个

我因为不知道这个而失败了一次面试。所以我写这篇文章,确保这种情况不会再发生在你身上。 锁定允许我们控制有多少线程可以访问代码中的某个部分。 为什么要这样做呢? 因为你想保护对昂贵资源的访问。而且你需要锁定提供的并发控制。由于我很少使用低级代码,所以我尝试使用lock语句来实现这一点。结果一切都变得一

零基础如何自学C#?

前言 本文来源于知乎的一个提问,提问的是一个大一软件工程专业的学生,他想要自学C#但是不知道该怎么去学,这让他感到很迷茫,希望有人能给他一些建议和提供一些学习方向。 个人建议 确认目标:自学C#首先你需要大概了解该门语言的发展、前景和基本特点,从自身实际情况和方向出发确认学习的必要性。 制定学习计划

一个库帮你轻松的创建漂亮的.NET控制台应用程序

前言 做过.NET控制台应用程序的同学应该都知道原生的.NET控制台应用程序输出的内容都比较的单调,假如要编写漂亮且美观的控制台输出内容或者样式可能需要花费不少的时间去编写代码和调试。今天大姚给大家分享一个.NET开源且免费的类库帮你轻松的创建漂亮、美观的.NET控制台应用程序:Spectre.Co

比较三种非破坏性处理数组的方法

在这篇文章中,我们将会探索处理数组的三种方法: - `for…of`循环 - 数组方法`.reduce()` - 数组方法`.flatMap()` 目的是帮助你在需要处理数组的时候在这些特性之间做出选择。如果你还不知道`.reduce()`和`.flatMap()`,这里将向你解释它们。 为了更好地