2022-10-7 About 29 min

本章将详细介绍 core-js

# 11.1 core-js 简介

core-js 是 JavaScript 标准库 API 的补丁集,现在,它已支持 ECMAScript 的部分提案 API、标准 API,同时也支持部分 WEB 标准。

比如,对于 Array.isArray() 方法,core-js 提供了补丁:

var toString = {}.toString;

function classof(it) {
  return toString.call(it).slice(8, -1);
};

Array.isArray = Array.isArray || function isArray(arg) {
  return classof(arg) == 'Array';
};
1
2
3
4
5
6
7
8
9

core-js 最初是作者为了满足自身项目需要开启的项目,提供一些补丁和工具函数,随后发布在社区,并越来越向标准化靠近,到现在,core-js 可以被认为是一个纯粹的标准库补丁集。

core-js 通常应用内置在 Babel 插件体系里,开发者以前较少用到,但它已经是前端开发的一个基础设施了。

# 11.2 core-js@2 与 core-js@3

截至 2021 年 2 月,core-js 广泛应用的有两个版本: core-js@2core-js@3,其中 core-js@2 已经停止更新,建议使用 core-js@3 版本。

本身编写时,能看到 core-js@4 的一些注释了,也许本书出版的时候 core-js@4 已经发布

下表是 core-js@2core-js@3 的部分区别:

core-js@2 core-js@3
是否更新 不再更新 更新中
性能 包体积较大(~2M) 包进行了拆分: core-js/core-js-pure/core-js-compat
特性支持 在 @2 的基础上,删除一些过时特性
在 @2 的基础上,新增对 web 标准的支持

在此,我们主要了解 core-js@3 版本的使用和原理,下文中如不特殊标注版本,均被认为是 core-js@3。其与 core-js@2 的差异,书中也会介绍。

core-js@3 的特点:

  • core-js 支持最新的 ECMAScript 标准

  • core-js 支持 ECMAScript 标准库提案

  • core-js 支持一些 WHATWG/W3C 标准

  • core-js 最大限度提供模块化定义,使之可按需使用

  • core-js 支持污染和不污染全局变量的能力

  • core-js 和 Babel 紧密集成,便于项目使用

# 11.3 core-js@3 子模块分类

core-js@3 是 monorepo 项目,基于 lerna 进行模块管理,其核心 package 包括:

  1. core-js/packages/core-js/
  2. core-js/packages/core-js-builder/
  3. core-js/packages/core-js-bundle/
  4. core-js/packages/core-js-compat/
  5. core-js/packages/core-js-pure/

接下来将介绍上述模块。

  • core-js/packages/core-js/

    定义全局的补丁(~500KB,压缩并且 gzipped 处理后 40KB)。

    core-js 支持 ECMAScript 标准、ECMAScript 提案、一些 WEB 标准(WHATWG/W3C),也支持模块化。这些特点的实现,主要在 core-js/packages/core-js/ 目录里。源码中有以下约定:

    • ECMAScript 标准中的 API,以 es.xx.js 命名,如 es.array.every.js
    • ECMAScript 提案中的 API,以 esnext.xx.js 命名,如 esnext.map.of.js
    • WEB 标准中的 API,以 web.xx.js 命名,如 web.url-search-params.js

    下表是 core-js/packages/core-js 各子模块的功能以及对各个标准的支持情况:

    目录/文件 描述 支持ES标准 支持ES提案 支持WEB标准
    packages/core-js/index.js 全部补丁,包括 ECMAScript 标准、ECMAScript 提案、WEB 标准
    packages/core-js/es/ 进入 ECMAScript 标准的 API ×
    packages/core-js/features/ 包含 es/web/proposals/ 目录下的所有 API √ ?
    packages/core-js/stable/ 稳定的 API,包括 ECMAScript 标准、WEB 标准 ×
    packages/core-js/web/ WEB 标准 API × ×
    packages/core-js/proposals/ index.js 指向 stage/ 目录,间接指向 stage-0/ 目录。目录内其他文件均为试验阶段的 ES API × ×
    packages/core-js/stage/ index.js 指向 stage-0/ 目录,目录内其他文件分别指向 stage0~4 ×
    packages/core-js/internals/ 内部使用的工具函数,含 API 具体实现,不用于对外服务
    packages/core-js/modules/ 提供 API 最终定义;文件命名与当前支持的阶段和标准相关。
  • core-js/packages/core-js-pure

    提供了不污染全局变量的补丁,即模块化的使用。和 core-js@2 中的 core-js/library 相当(~440KB)。

    举例:

    // 局部变量
    import from from 'core-js-pure/stable/array/from';
    import flat from 'core-js-pure/stable/array/flat';
    import Set from 'core-js-pure/stable/set';
    import Promise from 'core-js-pure/stable/promise';
    
    from(new Set([1, 2, 3, 2, 1]));
    flat([1, [2, 3], [4, [5]]], 2);
    Promise.resolve(32).then(x => console.log(x));
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
  • core-js/packages/core-js-bundle

    core-js-bundle 是一个完整的 core-js 打包后的版本,提供全局补丁定义。

    可以在浏览器环境使用:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script src="https://unpkg.com/core-js-bundle@3.16.2/minified.js"></script>
    </head>
    <body>
        <script>
            console.log(globalThis.Array === Array); // true
        </script>
    </body>
    </html>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    也可以在 Node 环境使用:

    require('core-js-bundle');
    console.log(globalThis.Array === Array); // true
    
    1
    2
  • core-js/packages/core-js-compat

    core-js-compat 提供了目标环境对应的 core-js 需要提供的功能模块。

# 11.4 core-js 中的补丁

这里介绍一下 core-js 中某些 API 的补丁。

# 准备工作

core-js 内部提供了一个通用的工具方法(这里命名为 $),该方法定义在文件 core-js/packages/core-js/internals/export.js,类型定义如下。

module.exports = (options: object; source: object): void
1

该方法提供了一种快捷方式,将补丁实现快速应用在目标对象上。

比如,core-js/packages/core-js/modules/es.object.is.js 定义了 Object.is 方法的补丁,通用方法 $ 是这样为 Object 对象添加 is() 方法的:

var $ = require('../internals/export'); // 通用的工具方法 $
var is = require('../internals/same-value');

// `Object.is` method
// https://tc39.es/ecma262/#sec-object.is
$({ target: 'Object', stat: true }, {
    is: is
});
1
2
3
4
5
6
7
8

$ 方法中,options 对象是配置项,在该例中指的是 { target: 'Object', stat: true }source 对象描述了补丁的具体实现,在该例中指的是 { is: is }

上述配置的目的是将 is() 方法添加到 Object 对象作为其静态方法: Object.is()

以下是 options 各配置项的含义:

  • target: string | undefined

    描述 source 中的属性名要添加到的目标对象。

  • global: boolean

    source 中的属性名要添加到的目标对象是否是全局对象。

    es.parse-float.js 为例:

    var $ = require('../internals/export');
    var parseFloatImplementation = require('../internals/number-parse-float');
    
    // `parseFloat` method
    // https://tc39.es/ecma262/#sec-parsefloat-string
    $({ global: true, forced: parseFloat != parseFloatImplementation }, {
        parseFloat: parseFloatImplementation
    });
    
    1
    2
    3
    4
    5
    6
    7
    8

    其配置的 global: true 意味着,parseFloat 会被添加到全局对象上。

    es.object.keys.js 为例:

    // `Object.keys` method
    // https://tc39.es/ecma262/#sec-object.keys
    $({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES }, {
        keys: function keys(it) {
            return nativeKeys(toObject(it));
        }
    });
    
    1
    2
    3
    4
    5
    6
    7

    其没有配置 global: true,且配置的 stat: true,意味着,keys() 方法被设置在了 Object 对象上,构成了 Object.keys() 方法。

  • stat: boolean

    source 对象中的属性名是否是 target 的静态属性/方法。

  • proto: boolean

    是否添加到 target 描述的对象的 prototype上。

    例如,es.array.copy-within.js 的内容是:

    // `Array.prototype.copyWithin` method
    // https://tc39.es/ecma262/#sec-array.prototype.copywithin
    $({ target: 'Array', proto: true }, {
        copyWithin: copyWithin
    });
    
    1
    2
    3
    4
    5

    copyWithin 方法被设置到了 Array.prototype.copyWithin

  • real

  • forced: boolean

    是否强制覆盖原生实现。

  • bind

  • wrap

  • unsafe

  • sham

  • enumerable: boolean

  • noTargetGet: boolean

# ECMAScript 标准的补丁

ECMAScript 标准涉及的特性比较多,笔者根据标准描述及 core-js 的文档/源码,整理了 ECMAScript 标准特性及其在 core-js 的实现路径。

# ECMAScript: Object

  • 特性列表

    分类 特性 路径
    es.object core-js(-pure)/es|stable|features/object
    es.object.assign core-js(-pure)/es|stable|features/object/assign
    es.object.is core-js(-pure)/es|stable|features/object/is
    es.object.set-prototype-of core-js(-pure)/es|stable|features/object/set-prototype-of
    es.object.get-prototype-of core-js(-pure)/es|stable|features/object/get-prototype-of
    es.object.get-own-property-descriptor core-js(-pure)/es|stable|features/object/get-own-property-descriptor
    es.object.get-own-property-descriptors core-js(-pure)/es|stable|features/object/get-own-property-descriptors
    es.object.keys core-js(-pure)/es|stable|features/object/keys
    es.object.values core-js(-pure)/es|stable|features/object/values
    es.object.entries core-js(-pure)/es|stable|features/object/entries
    es.object.get-own-property-names core-js(-pure)/es|stable|features/object/get-own-property-names
    es.object.freeze core-js(-pure)/es|stable|features/object/freeze
    es.object.from-entries core-js(-pure)/es|stable|features/object/from-entries
    es.object.seal core-js(-pure)/es|stable|features/object/seal
    es.object.prevent-extensions core-js(-pure)/es|stable|features/object/prevent-extensions
    es.object.is-frozen core-js(-pure)/es|stable|features/object/is-frozen
    es.object.is-sealed core-js(-pure)/es|stable|features/object/is-sealed
    es.object.is-extensible core-js(-pure)/es|stable|features/object/is-extensible
    es.object.to-string core-js/es|stable|features/object/to-string
    es.object.create core-js(-pure)/es|stable|features/object/create
    es.object.define-property core-js(-pure)/es|stable|features/object/define-property
    es.object.define-properties core-js(-pure)/es|stable|features/object/define-properties
    es.object.define-getter core-js(-pure)/es|stable|features/object/define-getter
    es.object.define-setter core-js(-pure)/es|stable|features/object/define-setter
    es.object.lookup-getter core-js(-pure)/es|stable|features/object/lookup-getter
    es.object.lookup-setter core-js(-pure)/es|stable|features/object/lookup-setter
  • 重点实现

    TODO

# ECMAScript: Function

  • 特性列表

    分类 特性 路径
    es.function core-js/es|stable|features/function
    es.function.name core-js/es|stable|features/function/name
    es.function.has-instance core-js/es|stable|features/function/has-instance
    es.function.bind core-js/es|stable|features/function/bind
    core-js/es|stable|features/function/virtual/bind
  • 重点实现

    TODO

# ECMAScript: Array

  • 特性列表

    分类 特性 路径
    es.array core-js(-pure)/es|stable|features/array
    es.array.from core-js(-pure)/es|stable|features/array/from
    es.array.is-array core-js(-pure)/es|stable|features/array/is-array
    es.array.of core-js(-pure)/es|stable|features/array/of
    es.array.copy-within core-js(-pure)/es|stable|features/array/copy-within
    es.array.fill core-js(-pure)/es|stable|features/array/fill
    es.array.find core-js(-pure)/es|stable|features/array/find
    es.array.find-index core-js(-pure)/es|stable|features/array/find-index
    es.array.iterator core-js(-pure)/es|stable|features/array/iterator
    es.array.includes core-js(-pure)/es|stable|features/array/includes
    es.array.slice core-js(-pure)/es|stable|features/array/slice
    es.array.join core-js(-pure)/es|stable|features/array/join
    es.array.index-of core-js(-pure)/es|stable|features/array/index-of
    es.array.last-index-of core-js(-pure)/es|stable|features/array/last-index-of
    es.array.every core-js(-pure)/es|stable|features/array/virtual/every
    es.array.some core-js(-pure)/es|stable|features/array/virtual/some
    es.array.for-each core-js(-pure)/es|stable|features/array/for-each
    es.array.map core-js(-pure)/es|stable|features/array/map
    es.array.filter core-js(-pure)/es|stable|features/array/filter
    es.array.reduce core-js(-pure)/es|stable|features/array/reduce
    es.array.reduce-right core-js(-pure)/es|stable|features/array/reduce-right
    es.array.reverse core-js(-pure)/es|stable|features/array/reverse
    es.array.sort core-js(-pure)/es|stable|features/array/sort
    es.array.flat core-js(-pure)/es|stable|features/array/flat
    es.array.flat-map core-js(-pure)/es|stable|features/array/flat-map
    es.array.unscopables.flat ??
    es.array.unscopables.flat-map ??
    es.array.at core-js(-pure)/es|stable|features/array/at
  • 重点实现

    TODO

# ECMASCript: String and RegExp

  • 特性列表

    分类 特性 路径
    es.string core-js(-pure)/es|stable|features/string
    es.string.from-code-point core-js(-pure)/es|stable|features/string/from-code-point
    es.string.raw core-js(-pure)/es|stable|features/string/raw
    es.string.iterator core-js(-pure)/es|stable|features/string(/virtual)/iterator
    es.string.split core-js/es|stable|features/string/split
    es.string.code-point-at core-js(-pure)/es|stable|features/string(/virtual)/code-point-at
    es.string.ends-with core-js(-pure)/es|stable|features/string(/virtual)/ends-with
    es.string.includes core-js(-pure)/es|stable|features/string(/virtual)/includes
    es.string.repeat core-js(-pure)/es|stable|features/string(/virtual)/repeat
    es.string.pad-start core-js(-pure)/es|stable|features/string(/virtual)/pad-start
    es.string.pad-end core-js(-pure)/es|stable|features/string(/virtual)/pad-end
    es.string.starts-with core-js(-pure)/es|stable|features/string(/virtual)/starts-with
    es.string.trim core-js(-pure)/es|stable|features/string(/virtual)/trim
    es.string.trim-start core-js(-pure)/es|stable|features/string(/virtual)/trim-start
    es.string.trim-end core-js(-pure)/es|stable|features/string(/virtual)/trim-end
    es.string.match-all core-js(-pure)/es|stable|features/string(/virtual)/match-all
    es.string.replace-all core-js(-pure)/es|stable|features/string(/virtual)/replace-all
    es.string.at-alternative ??
    es.string.match core-js/es|stable|features/string/match
    es.string.replace core-js/es|stable|features/string/replace
    es.string.search core-js/es|stable|features/string/search
    es.string.split core-js/es|stable|features/string/split
    es.string.anchor core-js(-pure)/es|stable|features/string(/virtual)/anchor
    es.string.big core-js(-pure)/es|stable|features/string(/virtual)/big
    es.string.blink core-js(-pure)/es|stable|features/string(/virtual)/blink
    es.string.bold core-js(-pure)/es|stable|features/string(/virtual)/bold
    es.string.fixed core-js(-pure)/es|stable|features/string(/virtual)/fixed
    es.string.fontcolor core-js(-pure)/es|stable|features/string(/virtual)/fontcolor
    es.string.fontsize core-js(-pure)/es|stable|features/string(/virtual)/fontsize
    es.string.italics core-js(-pure)/es|stable|features/string(/virtual)(/virtual)/italics
    es.string.link core-js(-pure)/es|stable|features/string(/virtual)/link
    es.string.small core-js(-pure)/es|stable|features/string(/virtual)/small
    es.string.strike core-js(-pure)/es|stable|features/string(/virtual)/strike
    es.string.sub core-js(-pure)/es|stable|features/string(/virtual)/sub
    es.string.sup core-js(-pure)/es|stable|features/string(/virtual)/sup
    es.string.substr core-js(-pure)/es|stable|features/string(/virtual)/substr
    es.escape core-js/es|stable|features/escape
    es.unescape core-js/es|stable|features/unescape
    es.regexp core-js/es|stable|features/regexp
    es.regexp.constructor core-js/es|stable|features/regexp/constructor
    es.regexp.dot-all core-js/es|stable|features/regexp/dot-all
    es.regexp.flags core-js(-pure)/es|stable|features/regexp/flags
    es.regexp.sticky core-js/es|stable|features/regexp/sticky
    es.regexp.test core-js/es|stable|features/regexp/test
  • 重点实现

    TODO

# ECMAScript: Number

  • 特性列表

    分类 特性 路径
    es.number core-js(-pure)/es|stable|features/number
    es.number.constructor core-js/es|stable|features/number/constructor
    es.number.epsilon core-js(-pure)/es|stable|features/number/epsilon
    es.number.is-finite core-js(-pure)/es|stable|features/number/is-finite
    es.number.is-integer core-js(-pure)/es|stable|features/number/is-integer
    es.number.is-nan core-js(-pure)/es|stable|features/number/is-nan
    es.number.is-safe-integer core-js(-pure)/es|stable|features/number/is-safe-integer
    es.number.max-safe-integer core-js(-pure)/es|stable|features/number/max-safe-integer
    es.number.min-safe-integer core-js(-pure)/es|stable|features/number/min-safe-integer
    es.number.parse-float core-js(-pure)/es|stable|features/parse-float
    es.number.parse-int core-js(-pure)/es|stable|features/parse-int
    es.number.to-fixed core-js(-pure)/es|stable|features/number/to-fixed
    es.number.to-precision core-js(-pure)/es|stable|features/number/to-precision
    es.parse-int core-js(-pure)/es|stable|features/parse-int
    es.parse-float core-js(-pure)/es|stable|features/parse-float
  • 重点实现

    TODO

# ECMAScript: Math

  • 特性列表

    分类 特性 路径
    es.math core-js(-pure)/es|stable|features/math
    es.math.acosh core-js(-pure)/es|stable|features/math/acosh
    es.math.asinh core-js(-pure)/es|stable|features/math/asinh
    es.math.atanh core-js(-pure)/es|stable|features/math/atanh
    es.math.cbrt core-js(-pure)/es|stable|features/math/cbrt
    es.math.clz32 core-js(-pure)/es|stable|features/math/clz32
    es.math.cosh core-js(-pure)/es|stable|features/math/cosh
    es.math.expm1 core-js(-pure)/es|stable|features/math/expm1
    es.math.fround core-js(-pure)/es|stable|features/math/fround
    es.math.hypot core-js(-pure)/es|stable|features/math/hypot
    es.math.imul core-js(-pure)/es|stable|features/math/imul
    es.math.log10 core-js(-pure)/es|stable|features/math/log10
    es.math.log1p core-js(-pure)/es|stable|features/math/log1p
    es.math.log2 core-js(-pure)/es|stable|features/math/log2
    es.math.sign core-js(-pure)/es|stable|features/math/sign
    es.math.sinh core-js(-pure)/es|stable|features/math/sinh
    es.math.tanh core-js(-pure)/es|stable|features/math/tanh
    es.math.trunc core-js(-pure)/es|stable|features/math/trunc
  • 重点实现

    TODO

# ECMAScript: Date

  • 特性列表

    分类 特性 路径
    es.date core-js/es|stable|features/date
    es.date.to-string core-js/es|stable|features/date/to-string
    es.date.now core-js(-pure)/es|stable|features/date/now
    es.date.to-iso-string core-js(-pure)/es|stable|features/date/to-iso-string
    es.date.to-json core-js(-pure)/es|stable|features/date/to-json
    es.date.to-primitive core-js(-pure)/es|stable|features/date/to-primitive
    es.date.get-year core-js(-pure)/es|stable|features/date/get-year
    es.date.set-year core-js(-pure)/es|stable|features/date/set-year
    es.date.to-gmt-string core-js(-pure)/es|stable|features/date/to-gmt-string
  • 重点实现

    TODO

# ECMAScript: Promise

  • 特性列表

    分类 特性 路径
    es.aggregate-error core-js(-pure)/es|stable|features/aggregate-error
    es.promise core-js(-pure)/es|stable|features/promise
    es.promise.all-settled core-js(-pure)/es|stable|features/promise/all-settled
    es.promise.any core-js(-pure)/es|stable|features/promise/any
    es.promise.finally core-js(-pure)/es|stable|features/promise/finally
  • 重点实现

    TODO

# ECMAScript: Symbol

  • 特性列表

    分类 特性 路径
    es.symbol core-js(-pure)/es|stable|features/symbol
    es.symbol.async-iterator core-js(-pure)/es|stable|features/symbol/async-iterator
    es.symbol.description core-js/es|stable|features/symbol/description
    es.symbol.has-instance core-js(-pure)/es|stable|features/symbol/has-instance
    es.symbol.is-concat-spreadable core-js(-pure)/es|stable|features/symbol/is-concat-spreadable
    es.symbol.iterator core-js(-pure)/es|stable|features/symbol/iterator
    es.symbol.match core-js(-pure)/es|stable|features/symbol/match
    es.symbol.replace core-js(-pure)/es|stable|features/symbol/replace
    es.symbol.search core-js(-pure)/es|stable|features/symbol/search
    es.symbol.species core-js(-pure)/es|stable|features/symbol/species
    es.symbol.split core-js(-pure)/es|stable|features/symbol/split
    es.symbol.to-primitive core-js(-pure)/es|stable|features/symbol/to-primitive
    es.symbol.to-string-tag core-js(-pure)/es|stable|features/symbol/to-string-tag
    es.symbol.unscopables core-js(-pure)/es|stable|features/symbol/unscopables
    core-js(-pure)/es|stable|features/symbol/for
    core-js(-pure)/es|stable|features/symbol/key-for
    core-js(-pure)/es|stable|features/object/get-own-property-symbols
  • 重点实现

    TODO

# ECMAScript: Collections

  • 特性列表

    分类 特性 路径
    Map es.map core-js(-pure)/es|stable|features/map
    Set es.set core-js(-pure)/es|stable|features/set
    WeakMap es.weak-map core-js(-pure)/es|stable|features/weak-map
    WeakSet es.weak-set core-js(-pure)/es|stable|features/weak-set
  • 重点实现

    TODO

# ECMAScript: Typed Arrays

  • 特性列表

    分类 特性 路径
    es.array-buffer core-js/es|stable|features/array-buffer
    es.array-buffer.constructor core-js/es|stable|features/array-buffer/constructor
    es.array-buffer.is-view core-js/es|stable|features/array-buffer/is-view
    es.array-buffer.slice core-js/es|stable|features/array-buffer/slice
    es.data-view core-js/es|stable|features/data-view
    es.typed-array core-js/es|stable|features/typed-array
    es.typed-array.int8-array core-js/es|stable|features/typed-array/int8-array
    es.typed-array.uint8-array core-js/es|stable|features/typed-array/uint8-array
    es.typed-array.uint8-clamped-array core-js/es|stable|features/typed-array/uint8-clamped-array
    es.typed-array.int16-array core-js/es|stable|features/typed-array/int16-array
    es.typed-array.uint16-array core-js/es|stable|features/typed-array/uint16-array
    es.typed-array.int32-array core-js/es|stable|features/typed-array/int32-array
    es.typed-array.uint32-array core-js/es|stable|features/typed-array/uint32-array
    es.typed-array.float32-array core-js/es|stable|features/typed-array/float32-array
    es.typed-array.float64-array core-js/es|stable|features/typed-array/float64-array
    es.typed-array.copy-within core-js/es|stable|features/typed-array/copy-within
    es.typed-array.every core-js/es|stable|features/typed-array/every
    es.typed-array.fill core-js/es|stable|features/typed-array/fill
    es.typed-array.filter core-js/es|stable|features/typed-array/filter
    es.typed-array.find core-js/es|stable|features/typed-array/find
    es.typed-array.find-index core-js/es|stable|features/typed-array/find-index
    es.typed-array.for-each core-js/es|stable|features/typed-array/for-each
    es.typed-array.from core-js/es|stable|features/typed-array/from
    es.typed-array.includes core-js/es|stable|features/typed-array/includes
    es.typed-array.index-of core-js/es|stable|features/typed-array/index-of
    es.typed-array.iterator core-js/es|stable|features/typed-array/iterator
    es.typed-array.last-index-of core-js/es|stable|features/typed-array/last-index-of
    es.typed-array.map core-js/es|stable|features/typed-array/map
    es.typed-array.of core-js/es|stable|features/typed-array/of
    es.typed-array.reduce core-js/es|stable|features/typed-array/reduce
    es.typed-array.reduce-right core-js/es|stable|features/typed-array/reduce-right
    es.typed-array.reverse core-js/es|stable|features/typed-array/reverse
    es.typed-array.set core-js/es|stable|features/typed-array/set
    es.typed-array.slice core-js/es|stable|features/typed-array/slice
    es.typed-array.some core-js/es|stable|features/typed-array/some
    es.typed-array.sort core-js/es|stable|features/typed-array/sort
    es.typed-array.subarray core-js/es|stable|features/typed-array/subarray
    es.typed-array.to-locale-string core-js/es|stable|features/typed-array/to-locale-string
    es.typed-array.to-string core-js/es|stable|features/typed-array/to-string
    es.typed-array.at core-js/es|stable|features/typed-array/at
  • 重点实现

    TODO

# ECMAScript: Reflect

  • 特性列表

    分类 特性 路径
    es.reflect core-js(-pure)/es|stable|features/reflect
    es.reflect.apply core-js(-pure)/es|stable|features/reflect/apply
    es.reflect.construct core-js(-pure)/es|stable|features/reflect/construct
    es.reflect.define-property core-js(-pure)/es|stable|features/reflect/define-property
    es.reflect.delete-property core-js(-pure)/es|stable|features/reflect/delete-property
    es.reflect.get core-js(-pure)/es|stable|features/reflect/get
    es.reflect.get-own-property-descriptor core-js(-pure)/es|stable|features/reflect/get-own-property-descriptor
    es.reflect.get-prototype-of core-js(-pure)/es|stable|features/reflect/get-prototype-of
    es.reflect.has core-js(-pure)/es|stable|features/reflect/has
    es.reflect.is-extensible core-js(-pure)/es|stable|features/reflect/is-extensible
    es.reflect.own-keys core-js(-pure)/es|stable|features/reflect/own-keys
    es.reflect.prevent-extensions core-js(-pure)/es|stable|features/reflect/prevent-extensions
    es.reflect.set core-js(-pure)/es|stable|features/reflect/set
    es.reflect.set-prototype-of core-js(-pure)/es|stable|features/reflect/set-prototype-of
  • 重点实现

    TODO

# ECMAScript: JSON

  • 特例列表

    分类 特性 路径
    es.json.to-string-tag core-js(-pure)/es|stable|features/json/to-string-tag
    es.json.stringify core-js(-pure)/es|stable|features/json/stringify
  • 重点实现

    TODO

# ECMAScript: globalThis

  • 特性列表

    分类 特性 路径
    es.global-this core-js(-pure)/es|stable|features/global-this
  • 重点实现

    文件 core-js/packages/core-js/internals/global.js 定义了全局对象的实现,代码如下:

    var check = function (it) {
        return it && it.Math == Math && it;
    };
    
    // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
    module.exports =
        // eslint-disable-next-line es/no-global-this -- safe
        check(typeof globalThis == 'object' && globalThis) ||
        check(typeof window == 'object' && window) ||
        // eslint-disable-next-line no-restricted-globals -- safe
        check(typeof self == 'object' && self) ||
        check(typeof global == 'object' && global) ||
        // eslint-disable-next-line no-new-func -- fallback
        (function () { return this; })() || Function('return this')();
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    可以看到,定义全局对象的过程有以下特点:

    • 判断全局对象的先后顺序

      依次是: globalThiswindowselfglobal、自定义方法获取。

    • 自定义方法获取全局对象

      用立即执行函数获取全局对象,优先使用 (function () { return this; })(),其次使用 Function('return this')()

    • 判断全局对象是否有效

      check 函数用于校验对象是否是有效的全局对象,判断该对象的 Math 属性是否和全局的 Math 变量一致。

# ECMAScript 提案的补丁

# Stage 4 proposals

  • 特性列表

    分类 特性 路径
    globalThis es.global-this core-js/proposals/global-this
    core-js(-pure)/es|stable|features/global-this
    String#matchAll es.string.match-all core-js/proposals/string-match-all
    core-js/es|stable|features/string/match-all
    String#replaceAll es.string.replace-all core-js/proposals/string-replace-all
    core-js/es|stable|features/string/replace-all
    Promise.allSettled es.promise.all-settled core-js/proposals/promise-all-settled
    core-js(-pure)/es|stable|features/promise/all-settled
    Promise.any es.promise.any core-js/proposals/promise-any
    core-js(-pure)/es|stable|features/promise/any
    Promise.any es.aggregate-error core-js(-pure)/es|stable|features/aggregate-error
    Object.prototype.hasOwnProperty es.object.has-own core-js/proposals/accessible-object-hasownproperty
    core-js(-pure)/es|stable|features/object/has-own
    es.array.at
    es.string.at-alternative
    Relative indexing method core-js/proposals/relative-indexing-method
    Relative indexing method es.typed-array.at core-js(-pure)/es|stable|features/array/at
    Relative indexing method core-js(-pure)/es|stable|features/string/at
    Relative indexing method es.typed-array.at core-js(-pure)/es|stable|features/typed-array/at
  • 重点实现

    TODO

# Stage 3 proposals

  • 特性列表

    分类 特性 路径
    esnext.array.find-last core-js(-pure)/features(/virtual)/array/find-last
    esnext.array.find-last-index core-js(-pure)/features(/virtual)/array/find-last-index
    esnext.typed-array.find-last core-js/features/typed-array/find-last
    esnext.typed-array.find-last-index core-js/features/typed-array/find-last-index
  • 重点实现

    TODO

# Stage 2 proposals

  • 特性列表

    分类 特性 路径
    Iterator helpers core-js/proposals/iterator-helpers
    Iterator helpers esnext.async-iterator.constructor
    Iterator helpers esnext.async-iterator.as-indexed-pairs core-js(-pure)/features/async-iterator/as-indexed-pairs
    Iterator helpers esnext.async-iterator.drop core-js(-pure)/features/async-iterator/drop
    Iterator helpers esnext.async-iterator.every core-js(-pure)/features/async-iterator/every
    Iterator helpers esnext.async-iterator.filter core-js(-pure)/features/async-iterator/filter
    Iterator helpers esnext.async-iterator.find core-js(-pure)/features/async-iterator/find
    Iterator helpers esnext.async-iterator.flat-map core-js(-pure)/features/async-iterator/flat-map
    Iterator helpers esnext.async-iterator.for-each core-js(-pure)/features/async-iterator/for-each
    Iterator helpers esnext.async-iterator.from core-js(-pure)/features/async-iterator/from
    Iterator helpers esnext.async-iterator.map core-js(-pure)/features/async-iterator/map
    Iterator helpers esnext.async-iterator.reduce core-js(-pure)/features/async-iterator/reduce
    Iterator helpers esnext.async-iterator.some core-js(-pure)/features/async-iterator/some
    Iterator helpers esnext.async-iterator.take core-js(-pure)/features/async-iterator/take
    Iterator helpers esnext.async-iterator.to-array core-js(-pure)/features/async-iterator/to-array
    Iterator helpers esnext.iterator.constructor
    Iterator helpers esnext.iterator.as-indexed-pairs core-js(-pure)/features/iterator/as-indexed-pairs
    Iterator helpers esnext.iterator.drop core-js(-pure)/features/iterator/drop
    Iterator helpers esnext.iterator.every core-js(-pure)/features/iterator/every
    Iterator helpers esnext.iterator.filter core-js(-pure)/features/iterator/filter
    Iterator helpers esnext.iterator.find core-js(-pure)/features/iterator/find
    Iterator helpers esnext.iterator.flat-map core-js(-pure)/features/iterator/flat-map
    Iterator helpers esnext.iterator.for-each core-js(-pure)/features/iterator/for-each
    Iterator helpers esnext.iterator.from core-js(-pure)/features/iterator/from
    Iterator helpers esnext.iterator.map core-js(-pure)/features/iterator/map
    Iterator helpers esnext.iterator.reduce core-js(-pure)/features/iterator/reduce
    Iterator helpers esnext.iterator.some core-js(-pure)/features/iterator/some
    Iterator helpers esnext.iterator.take core-js(-pure)/features/iterator/take
    Iterator helpers esnext.iterator.to-array core-js(-pure)/features/iterator/to-array
    esnext.set.difference`
    New Set methods core-js/proposals/set-methods
    New Set methods esnext.set.intersection core-js(-pure)/features/set/intersection
    New Set methods esnext.set.is-disjoint-from core-js(-pure)/features/set/is-disjoint-from
    New Set methods esnext.set.is-subset-of core-js(-pure)/features/set/is-subset-of
    New Set methods esnext.set.is-superset-of core-js(-pure)/features/set/is-superset-of
    New Set methods esnext.set.symmetric-difference core-js(-pure)/features/set/symmetric-difference
    New Set methods esnext.set.union core-js(-pure)/features/set/union
    Map.prototype.emplace esnext.map.emplace core-js(-pure)/features/map/emplace
    Map.prototype.emplace esnext.weak-map.emplace core-js(-pure)/features/weak-map/emplace
    Array.isTemplateObject esnext.array.is-template-object core-js/proposals/array-is-template-object
    core-js(-pure)/features/array/is-template-object
    esnext.symbol.dispose core-js(-pure)/features/symbol/dispose
    esnext.symbol.async-dispose core-js(-pure)/features/symbol/async-dispose
    esnext.symbol.metadata core-js/proposals/decorators
    core-js(-pure)/features/symbol/metadata
  • 重点实现

    TODO

# Stage 1 proposals

  • 特性列表

    分类 特性 路径
    esnext.observable core-js/proposals/observable
    core-js(-pure)/features/observable
    esnext.symbol.observable core-js(-pure)/features/symbol/observable
    esnext.set.add-all core-js(-pure)/features/set/add-all
    esnext.set.delete-all core-js(-pure)/features/set/delete-all
    esnext.set.every core-js(-pure)/features/set/every
    esnext.set.filter core-js(-pure)/features/set/filter
    esnext.set.find core-js(-pure)/features/set/find
    esnext.set.join core-js(-pure)/features/set/join
    esnext.set.map core-js(-pure)/features/set/map
    esnext.set.reduce core-js(-pure)/features/set/reduce
    esnext.set.some core-js(-pure)/features/set/some
    esnext.map.delete-all core-js(-pure)/features/map/delete-all
    esnext.map.every core-js(-pure)/features/map/every
    esnext.map.filter core-js(-pure)/features/map/filter
    esnext.map.find core-js(-pure)/features/map/find
    esnext.map.find-key core-js(-pure)/features/map/find-key
    esnext.map.group-by core-js(-pure)/features/map/group-by
    esnext.map.includes core-js(-pure)/features/map/includes
    esnext.map.key-by core-js(-pure)/features/map/key-by
    esnext.map.key-of core-js(-pure)/features/map/key-of
    esnext.map.map-keys core-js(-pure)/features/map/map-keys
    esnext.map.map-values core-js(-pure)/features/map/map-values
    esnext.map.merge core-js(-pure)/features/map/merge
    esnext.map.reduce core-js(-pure)/features/map/reduce
    esnext.map.some core-js(-pure)/features/map/some
    esnext.map.update core-js(-pure)/features/map/update
    esnext.weak-set.add-all core-js(-pure)/features/weak-set/add-all
    esnext.weak-set.delete-all core-js(-pure)/features/weak-set/delete-all
    esnext.weak-map.delete-all core-js(-pure)/features/weak-map/delete-all
    esnext.set.of core-js(-pure)/features/weak-set/of
    esnext.set.from core-js(-pure)/features/weak-set/from
    esnext.map.of core-js(-pure)/features/weak-map/of
    esnext.map.from core-js(-pure)/features/weak-map/from
    esnext.weak-set.of core-js(-pure)/features/weak-set/of
    esnext.weak-set.from core-js(-pure)/features/weak-set/from
    esnext.weak-map.of core-js(-pure)/features/weak-map/of
    esnext.weak-map.from core-js(-pure)/features/weak-map/from
    esnext.composite-key core-js/proposals/keys-composition
    core-js(-pure)/features/composite-key
    esnext.composite-symbol core-js(-pure)/features/composite-symbol
    esnext.array.filter-reject core-js(-pure)/features/weak-set/from
    esnext.esnext.array.filter-reject core-js/proposals/array-filtering
    core-js(-pure)/features/array(/virtual)/filter-reject
    esnext.typed-array.filter-reject core-js/features/typed-array/filter-reject
    esnext.array.group-by core-js/proposals/array-grouping
    core-js(-pure)/features/array(/virtual)/group-by
    esnext.typed-array.group-by core-js/features/typed-array/group-by
    esnext.array.unique-by core-js/proposals/array-unique
    core-js(-pure)/features/array(/virtual)/unique-by
    esnext.typed-array.unique-by core-js/features/typed-array/unique-by
    esnext.array.last-item core-js/proposals/array-last
    core-js/features/array/last-item
    esnext.array.last-index core-js/features/array/last-index
    esnext.number.range core-js/proposals/number-range
    core-js(-pure)/features/bigint/range
    esnext.bigint.range core-js(-pure)/features/number/range
    esnext.number.from-string core-js/proposals/number-from-string
    core-js(-pure)/features/number/from-string
    esnext.math.clamp core-js(-pure)/features/math/clamp
    esnext.math.deg-per-rad core-js(-pure)/features/math/deg-per-rad
    esnext.math.degrees core-js(-pure)/features/math/degrees
    esnext.math.fscale core-js(-pure)/features/math/fscale
    esnext.math.rad-per-deg core-js(-pure)/features/math/rad-per-deg
    esnext.math.radians core-js(-pure)/features/math/radians
    esnext.math.scale core-js(-pure)/features/math/scale
    esnext.math.signbit core-js/proposals/math-signbit
    core-js(-pure)/features/math/signbit
    esnext.string.code-points core-js/proposals/string-code-points
    core-js(-pure)/features/string/code-points
    esnext.symbol.matcher core-js/proposals/pattern-matching
    core-js(-pure)/features/symbol/matcher
    esnext.math.seeded-prng core-js/proposals/seeded-random
    core-js(-pure)/features/math/seeded-prng
    core-js/proposals/object-iteration
    esnext.object.iterate-keys core-js(-pure)/features/object/iterate-keys
    esnext.object.iterate-values core-js(-pure)/features/object/iterate-values
    esnext.object.iterate-entries core-js(-pure)/features/object/iterate-entries
    esnext.promise.try core-js/proposals/promise-try
    core-js(-pure)/features/promise/try
  • 重点实现

    TODO

# Stage 0 proposals

  • 特性列表

    分类 特性 路径
    URL
    esnext.string.at core-js/proposals/string-at
    core-js(-pure)/features/string/at
    core-js(-pure)/features/string/virtual/
    core-js/proposals/efficient-64-bit-arithmetic
    esnext.math.iaddh core-js(-pure)/features/math/iaddh
    esnext.math.isubh core-js(-pure)/features/math/isubh
    esnext.math.imulh core-js(-pure)/features/math/imulh
    esnext.math.umulh core-js(-pure)/features/math/umulh
  • 重点实现

    TODO

# Pre-stage 0 proposals

  • 特性列表

    分类 特性 路径
    core-js/proposals/reflect-metadata
    esnext.reflect.define-metadata core-js(-pure)/features/reflect/define-metadata
    esnext.reflect.delete-metadata core-js(-pure)/features/reflect/delete-metadata
    esnext.reflect.get-metadata core-js(-pure)/features/reflect/get-metadata
    esnext.reflect.get-metadata-keys core-js(-pure)/features/reflect/get-metadata-keys
    esnext.reflect.get-own-metadata core-js(-pure)/features/reflect/get-own-metadata
    esnext.reflect.get-own-metadata-keys core-js(-pure)/features/reflect/get-own-metadata-keys
    esnext.reflect.has-metadata core-js(-pure)/features/reflect/has-metadata
    esnext.reflect.has-own-metadata core-js(-pure)/features/reflect/has-own-metadata
    esnext.reflect.metadata core-js(-pure)/features/reflect/metadata
  • 重点实现

    TODO

# WEB 标准 API 的补丁

# 特性列表

分类 模块 特性 路径
web.timers setTimeout core-js(-pure)/stable|features/set-timeout
web.timers setInterval core-js(-pure)/stable|features/set-interval
web.immediate setImmediate core-js(-pure)/stable|features/set-immediate
web.immediate clearImmediate core-js(-pure)/stable|features/clear-immediate
web.queue-microtask queueMicrotask core-js/web/queue-microtask
core-js(-pure)/stable|features/queue-microtask
web.url
web.url.to-json
web.url-search-params
web.dom-collections.iterator
web.dom-collections.for-each
web.dom-collections.iterator core-js(-pure)/stable|features/dom-collections/iterator
web.dom-collections.for-each core-js/stable|features/dom-collections/for-each
core-js-pure/es|stable|features/is-iterable
core-js-pure/es|stable|features/get-iterator
core-js-pure/es|stable|features/get-iterator-method

core-js 中和 WEB 标准相关的 API 实现,定义在 core-js/packages/core-js/web/ 目录下,并实现了以下 API:

# dom-collections

  • 介绍

    dom-collections 表示 HTML 中获取 DOM 节点集的一系列方法。

    下表是文件 core-js/packages/core-js/internals/dom-iterables.js 列举的 dom-collections:

    dom-collection 作用
    CSSRuleList
    CSSStyleDeclaration
    CSSValueList
    ClientRectList
    DOMRectList
    DOMStringList
    DOMTokenList
    DataTransferItemList
    FileList
    HTMLAllCollection
    HTMLCollection
    HTMLFormElement
    HTMLSelectElement
    MediaList
    MimeTypeArray
    NamedNodeMap
    NodeList
    PaintRequestList
    Plugin
    PluginArray
    SVGLengthList
    SVGNumberList
    SVGPathSegList
    SVGPointList
    SVGStringList
    SVGTransformList
    SourceBufferList
    StyleSheetList
    TextTrackCueList
    TextTrackList
    TouchList
  • 补丁

    core-js 为上述 dom-collection 方法添加了一系列补丁,目的是为其确保实现了 for-each/iterator 系列方法:

    require('../modules/web.dom-collections.for-each'); // 确保 for-each 实现
    require('../modules/web.dom-collections.iterator'); // 确保 iterator 实现
    var path = require('../internals/path');
    
    module.exports = path;
    
    1
    2
    3
    4
    5
    • for-each

      core-js 在文件 core-js/packages/core-js/internals/array-iteration.js 定义了和数组相关的多个方法的补丁,总体来说,forEach/map/filter/some/every/find/findIndex/filterOut 均用 for 循环实现。

      var global = require('../internals/global'); // 全局对象
      var DOMIterables = require('../internals/dom-iterables');
      var forEach = require('../internals/array-for-each'); // core-js 自身实现的 forEach
      var createNonEnumerableProperty = require('../internals/create-non-enumerable-property');
      
      // COLLECTION_NAME: CSSRuleList/CSSStyleDeclaration/CSSValueList/...
      for (var COLLECTION_NAME in DOMIterables) {
          var Collection = global[COLLECTION_NAME];
          var CollectionPrototype = Collection && Collection.prototype;
          // some Chrome versions have non-configurable methods on DOMTokenList
          if (CollectionPrototype && CollectionPrototype.forEach !== forEach) try {
              createNonEnumerableProperty(CollectionPrototype, 'forEach', forEach);
          } catch (error) {
              CollectionPrototype.forEach = forEach;
          }
      }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16

      从源码可以看出,core-js 会给浏览器支持的 dom-collections API,以 Object.defineProperty 或直接赋值的方式提供 forEach 方法实现。

    • iterator

      core-js 在 core-js/packages/core-js/modules/web.dom-collections.iterator.js 文件定义了对 iterator 的实现。

      TODO

# immediate

  • immediate介绍

    TODO

  • 兼容性判断

    core-js 提供了 setImmediate/clearImmediate 的兼容性实现。

    在文件 core-js/packages/core-js/modules/web.immediate.js 中可以看到,在实现 setImmediate 时,做出了以下处理:

    • 如果 setImmediate/clearImmediate 均已被支持,则不再处理

    • 如果 setImmediate/clearImmediate 有任何一个没有被支持,则手动实现 setImmediate/clearImmediate,并赋值到全局对象

      var FORCED = !global.setImmediate || !global.clearImmediate;
      
      // http://w3c.github.io/setImmediate/
      $({ global: true, bind: true, enumerable: true, forced: FORCED }, {
          // `setImmediate` method
          // http://w3c.github.io/setImmediate/#si-setImmediate
          setImmediate: task.set,
          // `clearImmediate` method
          // http://w3c.github.io/setImmediate/#si-clearImmediate
          clearImmediate: task.clear
      });
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
  • 补丁

    set = function setImmediate(fn) {
        var args = [];
        var i = 1;
        while (arguments.length > i) args.push(arguments[i++]);
    
        // 将 fn 推入队列
        queue[++counter] = function () {
            (typeof fn == 'function' ? fn : Function(fn)).apply(undefined, args);
        };
    
        // 将当前处理逻辑的索引注册到待执行函数
        // 待执行函数根据不同环境有不同实现
        defer(counter);
        
        // 返回数字形式的“句柄”
        return counter;
    };
    
    clear = function clearImmediate(id) {
        delete queue[id];
    };
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

    通过自定义的 setImmediate 方法,做到了:

    • 维护一个执行队列,按顺序执行处理逻辑,用 queue 数组维护
    • 将当前处理逻辑的索引注册到待执行函数,用 defer 方法实现,defer 会根据不同环境有不同的实现
    • 最终返回数字形式的“句柄”

    defer 的实现依据以下先后顺序:

    • process.nextTick: 如果是 Node 环境
    • Dispatch.now: 如果是 Sphere 游戏引擎环境
    • MessageChannel: 如果不是 iOS 环境,且支持 MessageChannel
    • postMessage: 如果支持 postMessage
    • createElement('script')onreadystatechange 事件
    • setTimeout

# queue-microtask

  • 介绍

    https://developer.mozilla.org/zh-CN/docs/Web/API/HTML_DOM_API/Microtask_guide

  • 补丁

    TODO

# timers

  • 介绍

    timers 指的就是 setTimeout/setInterval,二者的使用方式如下:

    • setTimeout(handler[, delay, arg1, arg2, ...])
    • setInterval(handler, delay, [arg1, arg2, ...])
  • 补丁

    core-js 对 timers 的补丁位于 core-js/packages/core-js/modules/web.timers.js,IE9 及以下版本会强制使用 core-js 自定义的实现。

    实现代码:

    var $ = require('../internals/export');
    var global = require('../internals/global');
    var userAgent = require('../internals/engine-user-agent');
    
    var slice = [].slice;
    var MSIE = /MSIE .\./.test(userAgent); // <- dirty ie9- check
    
    var wrap = function (scheduler) {
        return function (handler, timeout /* , ...arguments */) {
            var boundArgs = arguments.length > 2;
            var args = boundArgs ? slice.call(arguments, 2) : undefined;
            return scheduler(
                boundArgs 
                ? 
                function () {
                    (typeof handler == 'function' ? handler : Function(handler)).apply(this, args);
                } 
                : 
                handler, 
            
                timeout
            );
        };
    };
    
    // ie9- setTimeout & setInterval additional parameters fix
    // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers
    $({ global: true, bind: true, forced: MSIE }, {
        // `setTimeout` method
        // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-settimeout
        setTimeout: wrap(global.setTimeout),
        // `setInterval` method
        // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-setinterval
        setInterval: wrap(global.setInterval)
    });
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35

    可以看到,如果传入的 handler 不是函数,则用 Function(handler)).apply(this, args) 的方式调用

# url

core-js 对 url 的兼容性支持体现在三个子功能: URL 构造函数、URL.prototype.toJSONURLSearchParams 构造函数。

  • 对WAHTWG标准的兼容性判断

    core-js/packages/core-js/internals/native-url.js 文件描述了如何判断运行环境是否支持标准的 URLSearchParams:

    var fails = require('../internals/fails');
    var wellKnownSymbol = require('../internals/well-known-symbol');
    var IS_PURE = require('../internals/is-pure');
    
    var ITERATOR = wellKnownSymbol('iterator');
    
    // 返回值描述了宿主环节是否已支持 URLSearchParams
    module.exports = !fails(function () {
        var url = new URL('b?a=1&b=2&c=3', 'http://a');
        var searchParams = url.searchParams;
        var result = '';
        url.pathname = 'c%20d';
        searchParams.forEach(function (value, key) {
            searchParams['delete']('b');
            result += key + value;
        });
        return (IS_PURE && !url.toJSON)
            || !searchParams.sort
            || url.href !== 'http://a/c%20d?a=1&c=3'
            || searchParams.get('c') !== '3'
            || String(new URLSearchParams('?a=1')) !== 'a=1'
            || !searchParams[ITERATOR]
            // throws in Edge
            || new URL('https://a@b').username !== 'a'
            || new URLSearchParams(new URLSearchParams('a=b')).get('a') !== 'b'
            // not punycoded in Edge
            || new URL('http://тест').host !== 'xn--e1aybc'
            // not escaped in Chrome 62-
            || new URL('http://a#б').hash !== '#%D0%B1'
            // fails in Chrome 66-
            || result !== 'a1c3'
            // throws in Safari
            || new URL('http://x', undefined).host !== 'x';
    });
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34

    fails 方法接收一个执行函数,并在内部使用 try...catch... 执行该函数,若执行失败(有报错情况),fails() 方法返回 true,否则返回 false,这是 fails() 方法的实现:

    module.exports = function (exec) {
        try {
            return !!exec();
        } catch (error) {
            return true;
        }
    };
    
    1
    2
    3
    4
    5
    6
    7

    如果运行时环境不支持标准的 url 定义,core-js 会提供自己的 API 实现 url 的一些特性,如:

    • URL 构造函数的补丁定义在文件 core-js/packages/core-js/modules/web.url.js
    • URLSearchParams 的补丁定义在文件 core-js/packages/core-js/modules/web.url-search-params.js
  • 对 url 的统一处理

    core-js/packages/core-js/web/url.js 文件提供了对 url 各个特征的处理:

    require('../modules/web.url');
    require('../modules/web.url.to-json');
    require('../modules/web.url-search-params');
    
    1
    2
    3

    web.url.js 文件提供了基于 WHATWG 标准的各个特征的实现。

    web.url.to-json 提供了 URL.prototype.toJSON 的实现。

    web.url-search-params 提供了 URLSearchParams 的实现。

  • URL 构造函数

    TODO

  • URLSearchParams

    • 介绍

      URLSearchParams 接口定义了一些实用的方法来处理 URL 的查询字符串,比如:

      var paramsString = "q=URLUtils.searchParams&topic=api"
      var searchParams = new URLSearchParams(paramsString);
      
      for (let p of searchParams) {
          console.log(p);
      } // [ 'q', 'URLUtils.searchParams' ],[ 'topic', 'api' ]
      
      searchParams.has("topic") === true; // true
      searchParams.get("topic") === "api"; // true
      searchParams.getAll("topic"); // ["api"]
      searchParams.get("foo") === null; // true
      searchParams.append("topic", "webdev");
      searchParams.toString(); // "q=URLUtils.searchParams&topic=api&topic=webdev"
      searchParams.set("topic", "More webdev");
      searchParams.toString(); // "q=URLUtils.searchParams&topic=More+webdev"
      searchParams.delete("topic");
      searchParams.toString(); // "q=URLUtils.searchParams"
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17

      根据WHATWG的标准,core-js提供了不满足该标准的运行环境下的补丁。

    • 补丁

      TODO

  • URL.prototype.toJSON

    有独立的文件 core-js/packages/core-js/modules/web.url.to-json.js 描述了该实现:

    'use strict';
    var $ = require('../internals/export');
    
    // `URL.prototype.toJSON` method
    // https://url.spec.whatwg.org/#dom-url-tojson
    $({ target: 'URL', proto: true, enumerable: true }, {
        toJSON: function toJSON() {
            return URL.prototype.toString.call(this);
        }
    });
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    可以看到,toJSON 的实现和 toString 一致,注意,这里并没有涉及兼容性的处理,是因为 toString 方法在此之前已经被兼容性处理过了。

    不过,由于 web.url.js 也提供了 toJSON 的实现,这一步并没有必要了。

# 缺失的补丁

  • BigInt

    • 介绍

      TODO

    • 补丁缺失的原因

      TODO

  • Proxy

    • 介绍

      TODO

    • 补丁缺失的原因

      TODO

  • String#normalize

    • 介绍

      TODO

    • 补丁缺失的原因

      TODO

  • Intl

    • 介绍

      TODO

    • 补丁缺失的原因

      TODO

  • window.fetch

    • 介绍

      TODO

    • 补丁缺失的原因

      TODO

Last update: October 7, 2022 19:03
Contributors: hoperyy