首页 > 解决方案 > 如何使用 javaScript 文件作为其他 JavaScript 文件的高阶包装器

问题描述

我想问一下,因为在反应中我们有 HOC(高阶组件),我们在其中传递修改它的组件,然后返回修改后的组件以供使用

我们可以在 JavaScript 中做同样的事情吗?

例如

// index1.js
// this is file where i am importing all the folder modules and exporting them

export { methodA, methodB } from './xyzAB'
export { methodC, methodD } from './xyzCD'

我正在将这个文件导入到另一个文件夹中,像这样

import * as allMethods from './modules'

// this allows me to use this syntax
allMethods.methodA()
allMethods.methodB()

这工作正常,但我正在寻找这种包装

// index2.js 
// this is another file somewhere else where i want to use index1.js exported methods

import * as allMethods from './modules/xyz'
import anotherMethod from './somewhere/xyz'

// here i want customize some of `allMethods` functions and export them as new object
//which contains modifed version of default `index1.js` methods

allMethods.methodA = allMethods.methodA( anotherMethod ) // this is example of modified as HO Method


export default allMethods

我上面的例子可能看起来令人困惑,为什么我要寻找这样的解决方案,我有一组实用程序,我试图将它们作为库并在多个项目中使用它们,

现在一些实用程序依赖于主要项目相关的东西,所以我不想给我的实用程序硬编码引用它们的依赖项,我想通过我的高阶方法或配置文件为不同的方法传递不同的依赖项,以便每个新项目都通过它配置文件或更高阶包装文件中的依赖实用程序,如上图所示

我希望我能够澄清我的问题,

我尝试了几件事,我尝试将所有模块导入我算作包装文件的文件中,如果我尝试使用任何返回 webpack 错误的模块作为未定义的方法,由于方法直到几秒钟才完全加载,我尝试了 setTimeOut,效果很好,但这不是管理事物的有效方式,

然后我尝试了一些异步方式,我使用import()了返回承诺的动态,我使用了异步/等待语法,并且还使用了 .then 语法但无法提取数据并将其保存为变量(我可能在这一步做错了,但我完全失败了)但这仅适用于承诺或异步等待范围,

还尝试了其他步骤,

我希望我能找到一些更简洁的语法,如下所示

import * as F from '../../core/lib/functions'
import { getModel } from '../entities'

F.getKeys = F.getKeys( getModel )


export default F

欢迎任何建议

标签: javascriptreactjs

解决方案


我认为您正在寻找的是某种咖喱或类似工厂的模式。

没有高阶模块这样的东西,但由于 JavaScript 支持高阶函数,所以你应该使用它。

提醒一下,高阶组件是将组件作为参数并返回另一个组件的任何组件。类似地(简化),高阶函数是将函数作为参数并返回新函数的函数。(实际上所有 React 组件或多或少都是函数,因此我们能够拥有更高阶的组件)。

关键是你需要调用一个高阶函数,而不仅仅是导入它(同样,没有高阶模块之类的东西)。但这与您对依赖注入的想法密切相关。

我认为,你想要的是在你的实用程序中是这样的:

function a(dependency1, arg1, arg2) {}

function b(dependency2, arg1, arg2) {}

function createUtils(dependency1, dependency2) {
  return {
       a: a.bind(null, dependency1), 
       b: b.bind(null, dependency2) 
  } 
}

这允许您自定义每个项目的依赖项 1 和 2 以及它们如何工作的详细信息(使用一些通用接口)。使用绑定,您不必在每次调用函数时都传递该依赖项。

然后在你的一个项目中,你会设置它们是这样的:

import { createUtils} from 'utils';
import { dependency1, dependency2 } from 'somewhere' ;

const { a, b } = createUtils(dependency1, dependency2)

export { a, b };

你并没有真正做任何高阶函数的事情,就像我说的那样,这更像是工厂/依赖注入的事情。虽然bind是一个高阶函数(它接受调用它的函数并返回一个绑定了一些参数的新函数)。

您可以通过带有选项的另一个参数将位置放在 createUtils 中进行一般修改。或者,您可以为您希望能够修改的每种方法导出较小的“工厂”。

考虑到这一点,您可能只从 utils 导出原始函数并bind在模块设置代码中使用来绑定依赖项。我认为bind这是你所缺少的。以及您必须创建要导出的新函数,而不是修改导入的函数。这也意味着您在其余代码中的导入将仅来自您自己的模块,而不是来自 utils 模块。


推荐阅读