JavaScript 开发人员如何找到接口的实现类?

Ari*_*ial 3 javascript iterator iterable ecmascript-6 ecmascript-2016

我正在学习 JavaScript,我来自 Java。

Java 开发人员可以轻松评估接口的有用性,因为所有已知的实现类都已记录在案。请点击此处查看示例。

JavaScript 中情况并非如此。例如,对于可迭代对象,下面的链接仅显示了可迭代对象的几个示例。它们没有显示所有内置类和 DOM 类的实现。(例如,他们提到“像 NodeList 这样的集合类型也是可迭代的”。那么,除了 NodeList 之外,我怎样才能找到其他可迭代的 DOM 类?是否有一些我可以运行的 JS 代码来实现这一点?谢谢!)

JavaScript 开发人员如何找到接口的实现类?

谢谢!

关于可迭代的 MDN 文档:

更新1:

我正在寻找的是可以进入Array.from()第一个参数的迭代。谢谢!

Tho*_*ank 7

好吧,当谈到内置类时,我们最接近“接口”的可能是众所周知的符号,它告诉我们一个类是否实现了某些东西:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol#well-known_symbols

我们可以获取 globalThis(与浏览器中的 Window 对象相同,在 Node.js 中不同)对象的所有属性,大多数是类,是不可枚举的,所以我们必须使用Object.getOwnPropertyNames

然后我们可以循环遍历它们并查看它们的原型是否可迭代- 具有众所周知的符号Symbol.iterator。

我们现在将获得创建可迭代实例的类的广泛列表。

function getIterableClasses() {
  let classNames = [];
  let builtIn = Object.getOwnPropertyNames(globalThis);
  for (let x of builtIn) { 
    try {
      let object = globalThis[x].prototype;
      object[Symbol.iterator] && classNames.push(x);
    }
    catch (e) { }
  }
  return classNames.sort();
}

let c = getIterableClasses();
console.log('Found ' + c.length + ' iterable classes');
console.log(c.join('\n'));
Run Code Online (Sandbox Code Playgroud)

此代码报告了在 Chrome 中创建可迭代对象的 68 个内置类,在 Firefox 中创建了 58 个内置类,在 Safari 中创建了 57 个内置类(Mac 上的浏览​​器的最新版本,2023 年 5 月 6 日)。所以这样的类还是蛮多的。

注意:Node.js中,列表要小得多,因为它具有更加模块化的结构(需要时需要/导入模块)并且没有任何 DOM 相关的类,但您仍然可以获得 19 个具有可迭代实例的不同类Node.js:数组、BigInt64Array、BigUint64Array、缓冲区、Float32Array、Float64Array、FormData、标头、Int16Array、Int32Array、Int8Array、Map、Set、String、URLSearchParams、Uint16Array、Uint32Array、Uint8Array、Uint8ClampedArray

一位老师对另一位老师的个人想法:如果您的目的是教授基本的 JavaScript,我认为您对自己和您的学生来说都不利于完成所有这些课程。而是关注一些基础知识:数组是可迭代的,字符串是可迭代的,NodeList 是可迭代的(以及如何使用querySelectorAll来获取 NodeList)。事实上,您可以通过将任何可迭代对象扩展为数组[...iterable]将其转换为数组,这一事实通常很有用,因为您可以在其上使用标准数组方法(例如map、filter、reduce)。

另外:将一个 iterable 扩展到一个数组[...iterable]与Array.prototype.from 的作用大致相同,但以一种更短、更“JS 风格”的方式。

  • 为什么使用`Object.create`而不是直接使用`.prototype`? (4认同)
  • `if (x === 'getIterableClasses'){continue;}` 有什么意义? (2认同)
  • @Bergi:为了避免无限循环,因为如果在控制台/全局范围(这是运行它的自然位置)中运行,函数本身就会成为窗口的一部分 - 但那是在我使用 new 之前,我认为所以现在没有必要。接得好!将删除! (2认同)