JS Symbol

news/2024/12/1 0:28:27/

想起之前面经中的问题,为什么js对象不能用for…of去遍历,背了八股文的都会回答因为对象是不可迭代的数据类型,今天也是回头看了js的Symbol类型,并在此找到了这道题的满意答案。

在此记录一些js中Symbol常用的属性或方法。

1. Symbol.asyncIterator

根据 ECMAScript 规范,这个符号作为一个属性表示“一个方法,该方法返回对象默认AsyncIterator。 由for-await-of 语句使用”。换句话说,这个符号表示实现异步迭代器 API 的函数。
for-await-of循环会利用这个函数执行异步迭代操作。循环时,它们会调用以 Symbol.asyncIterator为键的函数,并期望这个函数会返回一个实现迭代器 API 的对象。很多时候,返回的对象是实现该 API 的 AsyncGenerator:

技术上,这个由 Symbol.asyncIterator 函数生成的对象应该通过其 next()方法陆续返回 Promise 实例。可以通过显式地调用 next()方法返回,也可以隐式地通过异步生成器函数返回:

class Emitter {max: number;asyncIdx: number;constructor(max: number) {this.max = max;this.asyncIdx = 0;}async *[Symbol.asyncIterator]() {while (this.asyncIdx < this.max) {yield new Promise((resolve) => resolve(this.asyncIdx++));}}
}async function asyncCount() {const emitter = new Emitter(5);for await(const x of emitter) {console.log(x);}
}asyncCount();

2. Symbol.hasInstance

根据 ECMAScript 规范,这个符号作为一个属性表示“一个方法,该方法决定一个构造器对象是否认可一个对象是它的实例。由instanceof 操作符使用”。instanceof 操作符可以用来确定一个对象实例的原型链上是否有原型。

在 ES6 中,instanceof 操作符会使用 Symbol.hasInstance 函数来确定关系。以 Symbol. hasInstance 为键的函数会执行同样的操作,只是操作数对调了一下

function Foo() {}
let f = new Foo();
console.log(Foo[Symbol.hasInstance](f)); // true
class Bar {}
let b = new Bar();
console.log(Bar[Symbol.hasInstance](b)); // true

这个属性定义在 Function 的原型上,因此默认在所有函数和类上都可以调用。由于 instanceof 操作符会在原型链上寻找这个属性定义,就跟在原型链上寻找其他属性一样,因此可以在继承的类上通过静态方法重新定义这个函数:

class Bar {}
class Baz extends Bar {static [Symbol.hasInstance](_: any) {return false;}
}
let b = new Baz(); 
console.log(Bar[Symbol.hasInstance](b)); // true 
console.log(b instanceof Bar); // true 
console.log(Baz[Symbol.hasInstance](b)); // false 
console.log(b instanceof Baz); // false

3. Symbol.iterator

根据 ECMAScript 规范,这个符号作为一个属性表示“一个方法,该方法返回对象默认的迭代器。 由 for-of语句使用”。换句话说,这个符号表示实现迭代器 API 的函数。
for-of循环这样的语言结构会利用这个函数执行迭代操作。循环时,它们会调用以 Symbol.iterator为键的函数,并默认这个函数会返回一个实现迭代器 API 的对象。很多时候,返回的对象是实现该 API 的 Generator:

例如我们知道对象是不可以被for of所迭代的,但是我们如果在其内部实现了Symbol.iterator方法,对象就可以被迭代。

const obj = {*[Symbol.iterator]() {for (let i = 0; i < 5; i++) {yield i;}}
};for (const iterator of obj) {console.log(iterator);
}
// 0 1 2 3 4

4. Symbol.toStringTag

根据 ECMAScript 规范,这个符号作为一个属性表示“一个字符串,该字符串用于创建对象的默认字符串描述。由内置方法Object.prototype.toString()使用”。
通过 toString()方法获取对象标识时,会检索由Symbol.toStringTag 指定的实例标识符,默认为"Object"。内置类型已经指定了这个值,但自定义类实例还需要明确定义:

class Foo {};
const foo = new Foo();console.log(foo); // Foo {}
console.log(foo.toString()); // [object Object]
console.log(foo[Symbol.toStringTag]); // undefinedclass Bar {constructor() {this[Symbol.toStringTag] = 'Bar';}
}
const bar = new Bar();
console.log(bar); // Bar { [Symbol(Symbol.toStringTag)]: 'Bar' }
console.log(bar.toString()); // [object Bar]
console.log(bar[Symbol.toStringTag]); // Barconst obj = {a: 1,[Symbol.toStringTag]: '1234'
}console.log(obj.toString()); // [object 1234]

5. 小小总结

以前在项目开发中很少用到Symbol就认为Symbol不重要,重新学习JS红宝书之后才发现js很多的方法和场景都是借助Symbol来实现的。学无止境,始终保持学习的热情和求知的精神,不断探索和发现新的知识和技能。


http://www.ppmy.cn/news/88876.html

相关文章

day37_Tomcat_Maven

今日内容 一、Maven 二、Tomcat 一、Maven 1.1 引言 项目管理问题 项目中jar包资源越来越多&#xff0c;jar包的管理越来越沉重。 繁琐 要为每个项目手动导入所需的jar&#xff0c;需要搜集全部jar 复杂 项目中的jar如果需要版本升级&#xff0c;就需要再重新搜集jar 冗余 相…

Python常见报错信息解决方案

Python常见问题解决指南 1.卸载Python时出现No Python 3.9 installation was detected的解决办法 https://blog.csdn.net/weixin_42768634/article/details/116150866 2.pip list 命令出现&#xff1a;“pip不是内部或外部命令…” https://www.cnblogs.com/technicist/p/1…

【leetCode】Maximum subArray 【剑指】礼物最大价值

参考资料&#xff1a;《剑指Offer》 53. Maximum Subarray Given an integer array nums, find the subarray with the largest sum, and return its sum. Example 1: Input: nums [-2,1,-3,4,-1,2,1,-5,4] Output: 6 Explanation: The subarray [4,-1,2,1] has the larges…

VanillaNet:深度学习极简主义的力量

摘要 基础模型的核心是“更多不同”的理念&#xff0c;计算机视觉和自然语言处理方面的出色表现就是例证。然而&#xff0c;Transformer模型的优化和固有复杂性的挑战要求范式向简单性转变。在本文中&#xff0c;我们介绍了VanillaNET&#xff0c;这是一种设计优雅的神经网络架…

从零开始 Spring Boot 33:Null-safety

从零开始 Spring Boot 33&#xff1a;Null-safety 图源&#xff1a;简书 (jianshu.com) Null-safety&#xff08;null安全&#xff09;实际上是Java这个“古老”语言的历史包袱&#xff0c;很多新的语言&#xff08;比如go或kotlin&#xff09;在诞生起就在语言层面提供对null…

C++基本介绍

文章目录 &#x1f96d;1.C基本介绍&#x1f9c2;1.1 C是什么&#x1f9c2;1.2 C发展史 &#x1f352;2. C的优势&#x1f954;2.1 语言的使用广泛度&#x1f954;2.2 C的应用领域 &#x1fad2;3. C学习计划 &#x1f96d;1.C基本介绍 &#x1f9c2;1.1 C是什么 C是一种通用…

苹果手机如何恢复删除的照片

在我们日常生活中&#xff0c;使用手机的时间越来越长&#xff0c;相应地也存储了更多的文件和数据。而这些数据中&#xff0c;照片无疑是我们最重要的一部分。但有时候&#xff0c;我们会误删除一些重要的照片&#xff0c;这时候&#xff0c;我们就需要知道苹果手机如何恢复删…

Android 差分包

一般而言&#xff0c;在开发过程中会有升级&#xff0c;目前主流使用的都是ota 差分包流程 那么如何编译差分包呢&#xff1f; 参考&#xff1a;https://blog.csdn.net/weixin_39641173/article/details/117569857 1、首先高通平台的编译流程与android原生态的编译流程一样&…