For AI agents: the complete documentation index is available at /tc39-atlas/llms.txt, the full documentation bundle is available at /tc39-atlas/llms-full.txt, and this page is available as Markdown at /tc39-atlas/proposals/proposal-extensions.md.
  • 简体中文
  • Extensions S1

    中文标题:扩展

    提案概览
    提案速览

    该提案引入了 :: 运算符,用于在对象上定义和使用扩展方法、getter 和 setter,而不会污染全局命名空间。它旨在通过允许临时扩展和复用内置原型来提高代码可读性,语法如 obj::method()obj::ext:name。` 相同。提案包含实验性实现和设计文档。

    Note

    以下 README 来自上游仓库,其中的阶段或状态标注可能滞后;当前信息以提案概览为准。

    扩展与 :: 运算符

    提案状态

    这是一个处于第 1 阶段的 ECMAScript(JavaScript)提案。

    注意:该提案可以被视为旧 bind 运算符提案 中“虚拟方法”部分的重塑,参见 https://github.com/tc39/proposal-bind-operator/issues/56。

    简单示例

    临时扩展方法和访问器的示例

    // 定义两个扩展方法
    const ::toArray = function () { return [...this] }
    const ::toSet = function () { return new Set(this) }
    
    // 定义一个扩展访问器
    const ::allDivs = {
    	get() { return this.querySelectorAll('div') }
    }
    
    // 复用内置原型方法和访问器
    const ::flatMap = Array.prototype.flatMap
    const ::size = Object.getOwnPropertyDescriptor(Set.prototype, 'size')
    
    // 使用扩展方法和访问器来计算
    // div 元素的所有类别的数量。
    let classCount = document::allDivs
    	::flatMap(e => e.classList::toArray())
    	::toSet()::size

    大致等于:

    // 定义两个扩展方法
    const $toArray = function () { return [...this] }
    const $toSet = function () { return new Set(this) }
    
    // 定义一个扩展访问器
    const $allDivs = {
    	get() { return this.querySelectorAll('div') }
    }
    
    // 复用内置原型方法和访问器
    const $flatMap = Array.prototype.flatMap
    const $size = Object.getOwnPropertyDescriptor(Set.prototype, 'size')
    
    // 使用扩展方法和访问器来计算
    // div 元素的所有类别的数量。
    let $
    $ = $allDivs.get.call(document)
    $ = $flatMap.call($, e => $toArray.call(e.classList))
    $ = $toSet.call($)
    $ = $size.get.call($)
    let classCount = $

    使用构造函数或命名空间对象作为扩展的示例

    // util.js
    export const toArray = iterable => [...iterable]
    export const toSet = iterable => new Set(iterable)
    import * as util from './util.js'
    
    const ::allDivs = {
    	get() { return this.querySelectorAll('div') }
    }
    
    let classCount = document::allDivs
    	::Array:flatMap(
    		e => e.classList::util:toArray())
    	::util:toSet()
    	::Set:size

    大致等于:

    import * as util from './util.js'
    
    const $allDivs = {
    	get() { return this.querySelectorAll('div') }
    }
    
    let $
    $ = $allDivs.get.call(document)
    $ = Array.prototype.flatMap.call($,
    	e => util.toArray(e.classList))
    $ = util.toSet($)
    $ = Object.getOwnPropertyDescriptor(Set.prototype, 'size').get.call($)
    let classCount = $

    旧 bind 运算符提案的变更

    • 保留 obj::foo() 语法用于扩展方法
    • obj::foo 重新用于扩展 getter,并添加 obj::foo = 作为扩展 setter
    • 为临时扩展方法和访问器提供单独的命名空间,不污染普通绑定名称
    • 添加 obj::ext:name 语法
    • 将运算符优先级改为与 . 相同
    • 移除 ::obj.foo(用例可以通过自定义扩展加库或其他提案解决)

    其他材料