【问题标题】:How to override a native class method in ES6?如何覆盖 ES6 中的原生类方法?
【发布时间】:2021-12-25 16:47:10
【问题描述】:

我正在尝试扩展 File 类并覆盖 stream()

class MyFile extends File {
    constructor (name, options) {
        super(name, options)
        this.customField = options.customField
    }

    stream () {
        return new ReadableStream({
            async start(controller) {
                /* implementation here */
            },
            async pull(controller) {
                /* implementation here */
            },
            async cancel() {
                /* implementation here */
            }
        })
    }

    async text () {
        // implementation here
    }

    async arrayBuffer () {
        // implementation here
    }

/* Attempt 2
    get [Symbol.toStringTag] () {
        return 'Blob'
    }
    
    static [Symbol.hasInstance] (object) {
        return true
    }
*/
}

当使用FileReader.readAsArrayBuffer()FileReader.readAsText()MyFile 时,它不会调用我的任何方法,而是只返回一个空的缓冲区/文本。然后我尝试删除extends File并在Attempt 2中添加代码,但现在抛出错误:Argument 1 ('blob') to FileReader.readAsArrayBuffer must be an instance of Blob

【问题讨论】:

  • 从您显示的代码中,无法判断。另外,我没有看到对 stream() 的呼叫。
  • "我正在尝试扩展 File 类并覆盖 stream()" - 为什么?你想做什么?你的信息流应该做些什么不同的事情?
  • @Bergi 我正在编写一个实现文件系统 API 的 Safari 扩展,并且规范说我应该返回一个 File。我无法控制网站如何处理这个 File 对象。
  • @osy 好的,但是您的扩展程序使用哪些文件以及如何生成它们?你不能只构造一个具有预期内容的新文件对象吗?
  • @Bergi 所以 iOS 根本不支持文件系统 API,我的扩展充当了原生文件读取 API 和 JS API 之间的桥梁。是的,我可以读取整个内容并返回一个 blob,但如果用户选择 4GB 文件怎么办?文件系统 API 的一大优势是您可以使用流 API 进行部分读取。

标签: ecmascript-6 es6-class


【解决方案1】:

这是不可能的。将FileReaderdirectly calls 插入Blobinternal getStream method,它不会在接收到的对象上调用.stream()

我怀疑File 是否打算被子类化。使用composition over inheritance,完全不要使用FileReader 来读取您的自定义文件。

【讨论】:

  • 我对该规范的理解是“获取流”是我正在覆盖的“Blob.stream()”。我相信如果这里的所有东西都实现为纯 JS,我会做的事情会奏效。但似乎一个本机代码调用另一个本机代码被允许采用“捷径”而不考虑继承。我对 JS 不够熟悉,不知道这是不是真的。
  • 不,Blob stream 方法使用与 FileReader 相同的“get stream”算法。是的,本机代码确实采用了捷径,它不调用blob.stream() JS 方法——这就是规范所说的。我认为该类并非旨在从中继承。如果您想获得权威的见解,可以open an issue :-)
  • 好的,我继续并引用了 WebKit 源代码,它直接调用 Blob C++ 对象(不通过 JSC)。这很不幸,但我也可以替换 FileReader。
猜你喜欢
  • 1970-01-01
  • 2018-07-08
  • 2019-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-30
  • 2020-11-05
  • 2017-02-14
相关资源
最近更新 更多