如何导出/导入仅包含原型扩展的JavaScript模块?
如何导出/导入仅包含原型扩展的JavaScript模块?
我有一个仅包含Date原型扩展的模块文件hijacks.js,没有任何导出语句,想在main.js中导入它并让扩展的方法生效,该怎么做?
我的代码示例
hijacks.js:
/// @source: https://stackoverflow.com/a/31810991/11186407 Date.prototype.getWeek = function() { let onejan = new Date(this.getFullYear(), 0, 1); let today = new Date(this.getFullYear(), this.getMonth(), this.getDate()); let dayOfYear = ((today - onejan + 86400000) / 86400000); return Math.ceil(dayOfYear / 7) }; /// @source: https://stackoverflow.com/a/5210450/11186407 Date.prototype.getFirstWeekDay = function() { // strip time away and set date and time to the beginning of the week-day let curr = new Date(this.toDateString()); curr.setHours(0); curr.setMinutes(0); curr.setSeconds(0); curr.setMilliseconds(0); let first = curr.getDate() - curr.getDay(); // First day is the day of the month - the day of the week return new Date(curr.setDate(first)); } /// @source: https://stackoverflow.com/a/5210450/11186407 Date.prototype.getLastWeekDay = function() { // strip time away and set date and time to the end of the week-day let curr = new Date(this.toDateString()); curr.setHours(23); curr.setMinutes(59); curr.setSeconds(59); curr.setMilliseconds(999); let first = curr.getDate() - curr.getDay(); // First day is the day of the month - the day of the week let last = first + 6; // last day is the first day + 6 return new Date(curr.setDate(last)); } /// @source: https://stackoverflow.com/a/5210450/11186407 Date.prototype.nextWeek = function() { this.setDate(this.getDate() + 7); } /// @source: https://stackoverflow.com/a/5210450/11186407 Date.prototype.previousWeek = function() { this.setDate(this.getDate() - 7); }
main.js(待修改):
import { ??? } from "./hijacks.js"; let d = new Date(); console.log(d.getWeek());
解决方案
核心逻辑:ES模块在被导入时,会执行模块内的所有顶层代码。你的hijacks.js里的代码都是直接修改Date.prototype,只要模块被加载执行,这些扩展就会生效,不需要导入任何具体变量。
方法1:直接导入模块(无需修改hijacks.js)
修改main.js的导入语句,不需要解构任何内容,直接导入整个模块:
// 导入模块并执行其代码,Date原型会被自动扩展 import "./hijacks.js"; let d = new Date(); console.log(d.getWeek()); // 现在可以正常调用扩展方法
方法2:给hijacks.js添加空导出(更符合ES模块规范)
有些环境可能要求模块必须有导出声明,你可以在hijacks.js的末尾添加一行空导出,不影响原有功能,但让模块符合规范:
// ... 原有原型扩展代码 ... // 添加空导出,符合ES模块要求 export {};
此时main.js的导入可以用两种写法,效果完全一致:
// 写法1:直接导入 import "./hijacks.js"; // 写法2:解构空导出(语义上更明确这是一个模块) import {} from "./hijacks.js"; let d = new Date(); console.log(d.getWeek());
注意事项
修改内置对象(比如Date)的原型属于侵入式修改,存在一定风险:
- 如果其他库也修改了
Date.prototype的同名方法,会出现覆盖冲突 - 可能影响后续的代码维护,其他开发者可能不知道原型被修改过
如果场景允许,更推荐使用工具函数而非原型扩展,比如把这些方法封装成独立的函数:
// utils.js export function getWeek(date) { let onejan = new Date(date.getFullYear(), 0, 1); let today = new Date(date.getFullYear(), date.getMonth(), date.getDate()); let dayOfYear = ((today - onejan + 86400000) / 86400000); return Math.ceil(dayOfYear / 7) }
然后在main.js中导入使用:
import { getWeek } from "./utils.js"; let d = new Date(); console.log(getWeek(d));
内容的提问来源于stack exchange,提问作者Moritz
相关产品推荐
相关产品推荐

