
core-js 的 ECMAScript Object 补丁全景模块清单、类型签名、入口点与实现原理【免费下载链接】core-jsStandard Library项目地址: https://gitcode.com/GitHub_Trending/co/core-js本文基于 core-js 仓库的官方文档 docs/web/docs/features/ecmascript/object.md系统梳理 ECMAScript 规范中Object内建对象在 core-js 中的全部补丁模块、TypeScript 类型签名、按需导入入口点并结合 packages/core-js/modules 下的真实源码剖析assign、groupBy、hasOwn、fromEntries、__proto__等关键方法的底层实现与兼容性修复策略。读完本文你将能够精准定位任意Object方法的补丁文件、正确选择最小化的导入路径并理解 core-js 如何在老引擎上还原 ES2015 语义。一、Object 相关补丁模块全景core-js 将 ES 规范中的每一个Object方法拆分为独立的模块文件统一放在 packages/core-js/modules 目录下命名规则为es.object.method.jses.前缀表示该特性已进入正式 ECMAScript 规范。原文档列出的完整模块清单如下es.object.assignes.object.createes.object.define-getteres.object.define-propertyes.object.define-propertieses.object.define-setteres.object.entrieses.object.freezees.object.from-entrieses.object.get-own-property-descriptores.object.get-own-property-descriptorses.object.get-own-property-nameses.object.get-prototype-ofes.object.group-byes.object.has-ownes.object.ises.object.is-extensiblees.object.is-frozenes.object.is-sealedes.object.keyses.object.lookup-getteres.object.lookup-setteres.object.prevent-extensionses.object.protoes.object.to-stringes.object.seales.object.set-prototype-ofes.object.values这些模块被聚合入口 packages/core-js/es/object/index.js 统一require并最终导出path.Object即全局Object本身。注意该聚合入口还会一并加载es.symbol、es.json.to-string-tag、es.math.to-string-tag、es.reflect.to-string-tag等关联模块——这是因为Symbol.toStringTag是Object.prototype.toString标签机制的基础。二、Built-ins 类型签名一份可校验的 API 契约原文档给出了Object补丁后完整 API 的 TypeScript 签名这是理解 core-js 覆盖范围最直接的参照class Object { toString(): string; // ES2015 fix: toStringTag support __defineGetter__(property: PropertyKey, getter: Function): void; __defineSetter__(property: PropertyKey, setter: Function): void; __lookupGetter__(property: PropertyKey): Function | void; __lookupSetter__(property: PropertyKey): Function | void; __proto__: Object | null; // required a way setting of prototype - will not in IE10-, its for modern engines like Deno static assign(target: Object, ...sources: ArrayObject): Object; static create(prototype: Object | null, properties?: { [property: PropertyKey]: PropertyDescriptor }): Object; static defineProperties(object: Object, properties: { [property: PropertyKey]: PropertyDescriptor })): Object; static defineProperty(object: Object, property: PropertyKey, attributes: PropertyDescriptor): Object; static entries(object: Object): Array[string, mixed]; static freeze(object: any): any; static fromEntries(iterable: Iterable[key, value]): Object; static getOwnPropertyDescriptor(object: any, property: PropertyKey): PropertyDescriptor | void; static getOwnPropertyDescriptors(object: any): { [property: PropertyKey]: PropertyDescriptor }; static getOwnPropertyNames(object: any): Arraystring; static getPrototypeOf(object: any): Object | null; static groupBy(items: Iterable, callbackfn: (value: any, index: number) key): { [key]: Arraymixed }; static hasOwn(object: object, key: PropertyKey): boolean; static is(value1: any, value2: any): boolean; static isExtensible(object: any): boolean; static isFrozen(object: any): boolean; static isSealed(object: any): boolean; static keys(object: any): Arraystring; static preventExtensions(object: any): any; static seal(object: any): any; static setPrototypeOf(target: any, prototype: Object | null): any; // required __proto__ - IE11 static values(object: any): Arraymixed; }几个值得注意的语义细节toString()标注为 ES2015 fix: toStringTag support旧引擎的原生toString不认识Symbol.toStringTagcore-js 通过 es.object.to-string 在检测到TO_STRING_TAG_SUPPORT不足时用内部实现 internals/object-to-string 覆盖Object.prototype.toString从而支持[object Foo]这类自定义标签输出。__proto__访问器注释明确指出在 IE10- 中不可用它面向的是 Deno 这类现代引擎。从源码 es.object.proto 看其修复条件是DESCRIPTORS getPrototypeOf setPrototypeOf ({}[PROTO] ! ObjectPrototype)即仅在原生缺失__proto__访问器时才通过defineBuiltInAccessor补上且 setter 内部会先用isPossiblePrototype校验新原型是否合法。setPrototypeOf与__proto__的依赖关系注释 required__proto__- IE11 说明在 IE11 上setPrototypeOf的可用性依赖__proto__访问器被正确安装。三、Entry Points按需加载的入口点清单core-js 的核心理念是只用多少加载多少。原文档给出了Object相关全部入口点路径模板为core-js(-pure)/es|stable|actual|full/object[/method]core-js(-pure)/es|stable|actual|full/object core-js(-pure)/es|stable|actual|full/object/assign core-js(-pure)/es|stable|actual|full/object/is core-js(-pure)/es|stable|actual|full/object/set-prototype-of core-js(-pure)/es|stable|actual|full/object/get-prototype-of core-js(-pure)/es|stable|actual|full/object/create core-js(-pure)/es|stable|actual|full/object/define-property core-js(-pure)/es|stable|actual|full/object/define-properties core-js(-pure)/es|stable|actual|full/object/get-own-property-descriptor core-js(-pure)/es|stable|actual|full/object/get-own-property-descriptors core-js(-pure)/es|stable|actual|full/object/group-by core-js(-pure)/es|stable|actual|full/object/has-own core-js(-pure)/es|stable|actual|full/object/keys core-js(-pure)/es|stable|actual|full/object/values core-js(-pure)/es|stable|actual|full/object/entries core-js(-pure)/es|stable|actual|full/object/get-own-property-names core-js(-pure)/es|stable|actual|full/object/freeze core-js(-pure)/es|stable|actual|full/object/from-entries core-js(-pure)/es|stable|actual|full/object/seal core-js(-pure)/es|stable|actual|full/object/prevent-extensions core-js/es|stable|actual|full/object/proto core-js(-pure)/es|stable|actual|full/object/is-frozen core-js(-pure)/es|stable|actual|full/object/is-sealed core-js(-pure)/es|stable|actual|full/object/is-extensible core-js/es|stable|actual|full/object/to-string core-js(-pure)/es|stable|actual|full/object/define-getter core-js(-pure)/es|stable|actual|full/object/define-setter core-js(-pure)/es|stable|actual|full/object/lookup-getter core-js(-pure)/es|stable|actual|full/object/lookup-setter入口点语法详解详见官方文档 docs/web/docs/usage.md命名空间层级es仅稳定 ES 特性→stable稳定 ES Web 标准→actual稳定 Web 标准 stage 3 提案→full全部特性含早期提案。官方建议优先使用/actual/因为它覆盖了所有实际可用的 JavaScript 特性又不包含主要用于实验的不稳定早期提案。pure 变体core-js-pure不污染全局命名空间适合库作者在依赖中安全使用core-js是全局版本。proto与to-string两个入口仅存在于core-js无-pure变体原因在于这两个模块直接修改Object.prototype无法在不污染原型的前提下以 pure 方式提供这与 pure 版本原型方法转换为静态方法的定位一致。实际使用示例import core-js/actual/object/group-by只加载Object.groupBy一个补丁import core-js/full/object则一次性加载上文聚合入口 packages/core-js/es/object/index.js 列出的全部es.object.*模块。仓库中已生成对应的具体入口文件例如 packages/core-js/es/object/assign.js、packages/core-js/es/object/group-by.js、packages/core-js/es/object/has-own.js。四、源码级原理关键方法的兼容性实现1.Object.assign针对 Edge 与 V8 旧版 Bug 的修复es.object.assign 本身只是一个薄壳真正逻辑位于 internals/object-assign.js。该文件先执行两个原生实现的缺陷检测Edge 顺序 Bug在属性 getter 动态新增不可枚举属性时原生assign的结果顺序错误V8 符号与顺序 Bug原生实现不复制Symbol键、或复制后属性顺序不稳定。只有Object.assign ! assign即检测失败时才注入自实现。自实现的关键点toObject(target)保证目标必须是对象否则抛TypeError对每个 source 使用IndexedObject包装兼容字符串等原始值键列表由objectKeys(S)与getOwnPropertySymbols(S)拼接而成即同时复制字符串键与符号键在无DESCRIPTORS不支持属性描述符的引擎时直接赋值否则仅复制可枚举属性propertyIsEnumerable过滤严格对齐规范的[[OwnPropertyKeys]]EnumerableOwnProperties语义。2.Object.groupBy处理原始值输入与 WebKit BugObject.groupBy是较新的 ES 特性实现见 es.object.group-by。源码先做特性检测var DOES_NOT_WORK_WITH_PRIMITIVES !nativeGroupBy || fails(function () { return nativeGroupBy(ab, function (it) { return it; }).a.length ! 1; });该检测针对 WebKit bug #271524——某些 WebKit 版本无法正确处理字符串等原始值输入。若检测失败则注入 polyfill其算法要点requireObjectCoercible(items)aCallable(callbackfn)做入参校验结果对象用create(null)创建无原型对象因此内部可安全使用key in obj判断键是否存在规避了部分 IE 版本在整数键上hasOwnProperty行为异常的问题iterate遍历可迭代对象toPropertyKey将回调返回值规范化为属性键doesNotExceedSafeInteger防止索引溢出新键用createProperty(obj, key, [value])创建数组已有键则push追加。3.Object.hasOwn、Object.fromEntries等薄封装es.object.has-own 直接复用内部工具 internals/has-own-property本质是规范化的Object.prototype.hasOwnProperty调用避免对象自带hasOwnProperty被覆盖导致的误判。es.object.from-entries 内部通过iterate(iterable, fn, { AS_ENTRIES: true })按[key, value]二元组迭代任意可迭代对象Map、数组、生成器等再用createProperty写入保证键始终被正确处理含符号键、数字键的字符串化。4.Object.prototype.__proto__面向 Deno 的访问器补丁es.object.proto 的源码注释特别提到Deno 2.9 patch this accessor, so we cant useinfor feature detection——即 Deno 较新版本会自行修补该访问器因此不能用__proto__ in {}这类方式做特性探测必须用({})[PROTO] ! ObjectPrototype判断实际值。补丁本身通过defineBuiltInAccessor在Object.prototype上安装configurable: true的 getter/settergetter 返回getPrototypeOf(toObject(this))setter 在原型合法isPossiblePrototype且目标为对象时才执行setPrototypeOf。5.Object.prototype.toStringtoStringTag修复es.object.to-string 在TO_STRING_TAG_SUPPORT为 false 时用 internals/object-to-string 覆盖原型上的toString。该实现会检查对象的Symbol.toStringTag输出[object Tag]格式同时保持对内置类型Array、Function、RegExp等标签的兼容。五、完整示例验证补丁后的行为以下是原文档给出的全部运行示例可直接在加载core-js后于任意支持环境执行验证let foo { q: 1, w: 2 }; let bar { e: 3, r: 4 }; let baz { t: 5, y: 6 }; Object.assign(foo, bar, baz); // foo { q: 1, w: 2, e: 3, r: 4, t: 5, y: 6 } Object.is(NaN, NaN); // true Object.is(0, -0); // false Object.is(42, 42); // true Object.is(42, 42); // false function Parent() { /* empty */ } function Child() { /* empty */ } Object.setPrototypeOf(Child.prototype, Parent.prototype); new Child() instanceof Child; // true new Child() instanceof Parent; // true ({ [Symbol.toStringTag]: Foo, }).toString(); // [object Foo] Object.keys(qwe); // [0, 1, 2] Object.getPrototypeOf(qwe) String.prototype; // true Object.values({ a: 1, b: 2, c: 3 }); // [1, 2, 3] Object.entries({ a: 1, b: 2, c: 3 }); // [[a, 1], [b, 2], [c, 3]] for (let [key, value] of Object.entries({ a: 1, b: 2, c: 3 })) { console.log(key); // a, b, c console.log(value); // 1, 2, 3 } const object { a: 1 }; Object.defineProperty(object, notWritable, { value: true, writable: false }); // Shallow object cloning with prototype and descriptors: Object.create(Object.getPrototypeOf(object), Object.getOwnPropertyDescriptors(object)); // {a: 1, notWritable: true} const target { a: 9 }; const source { b: 8 }; Object.defineProperty(source, notWritable, { value: true, writable: false }); // Mixin: Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); // {a: 9, b: 8, notWritable: true} const map new Map([[a, 1], [b, 2]]); Object.fromEntries(map); // { a: 1, b: 2 } class Unit { constructor(id) { this.id id; } toString() { return unit${ this.id }; } } const units new Set([new Unit(101), new Unit(102)]); Object.fromEntries(units.entries()); // { unit101: Unit { id: 101 }, unit102: Unit { id: 102 } } Object.hasOwn({ foo: 42 }, foo); // true Object.hasOwn({ foo: 42 }, bar); // false Object.hasOwn({}, toString); // false Object.groupBy([1, 2, 3, 4, 5], it it % 2); // { 1: [1, 3, 5], 0: [2, 4] }几个示例背后的实现佐证Object.keys(qwe)返回[0, 1, 2]、Object.getPrototypeOf(qwe)返回String.prototype说明 core-js 的补丁遵循规范对原始值primitive的ToObject装箱处理Object.create(Object.getPrototypeOf(object), Object.getOwnPropertyDescriptors(object))与Object.defineProperties(target, Object.getOwnPropertyDescriptors(source))两个组合分别演示了带原型与描述符的浅克隆和保留writable: false的 mixin它们的正确性依赖于getOwnPropertyDescriptors补丁如实返回描述符对象Object.groupBy的返回对象没有原型内部create(null)因此示例中得到的{ 1: [...], 0: [...] }是一个普通对象但不会携带Object.prototype上的键这在处理用户数据时更安全。六、与 Babel 生态的配合Object补丁同样深度集成于 Babel 工具链详见 docs/web/docs/usage.mdbabel/polyfill本质上就是core-js/stable与regenerator-runtime的组合现已废弃使用babel/preset-env时设置useBuiltIns: entry与corejs: 3.50建议精确到次版本号Babel 会按目标环境自动把import core-js/es拆解为仅必要的模块。例如针对chrome 71目标import core-js/stable可能被替换为import core-js/modules/es.object.from-entries等少量模块这正是入口点 模块拆分设计价值的体现。七、小结core-js 对 ECMAScriptObject的覆盖遵循一套高度模块化的工程模式每个方法一个es.object.*.js模块源码见 packages/core-js/modules通过特性检测决定是否注入 polyfill对外提供es/stable/actual/full四级命名空间与按方法细分的入口点对内依赖 packages/core-js/internals 中的原子工具函数保证语义严格对齐规范。无论是处理assign的 Edge/V8 顺序缺陷、groupBy的 WebKit 原始值缺陷还是__proto__在 Deno 等现代引擎上的访问器修补其核心思路都是优先使用原生实现、仅在检测到缺陷时注入等价实现这也是 core-js 能长期保持可靠性的根本原因。【免费下载链接】core-jsStandard Library项目地址: https://gitcode.com/GitHub_Trending/co/core-js创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考