在JavaScript中结合设计模式是一种好的实践吗?

4
目前我正在开发一个私人项目(用于学习),这是一个简单的待办事项清单。我尝试使用模块化模式(具体来说是揭示模块模式)。下面的图片展示了我构建它的大致想法。 我的应用程序外观的图片 因此,每个模块将在单独的js文件中,其中每个模块的结构如下:
var TaskModule = (function () { 

  function someFunction(parameter) {
    tasks = newTasks;
  }

}

这里有一个问题:如果我们想要创建像“帮助函数”这样的单独文件怎么办?在每个模块中编写类似于以下内容并不方便:
var someElement = document.getElementById('id')

我有一个辅助函数(此函数仅为示例):
var someElement = byId('id');

当然,我可以像其他模块一样创建HelpersModule,但是那样我就必须这样调用我的函数:
var someElement = HelpersModule.byId('id');

“这样会导致我的帮助函数不再有意义,因为它的长度不比使用document.getElementById更短。因此,为了避免每次调用帮助函数时都要输入前缀“HelpersModule”,我设计了我的HelpersModule如下:”
(function(window) {

    window.byId = function (selector, scope) {
      return (scope || document).getElementById(selector);
    };

})(window);

现在一切都运行良好,但我创建HelpersModule的方式与其他模块不一致。以不同的方式创建模块是不好的做法还是完全可以接受的?

1
你的 HelpersModule.byID()document.getElementById() 做的是同样的事情吗? - demogorgon
@demogorgon.net 是的,它确实可以,但这只是一个例子。 - pastuszkam
1
如果你的模块旨在完成不同的任务(一个初始化对象,而另一个提供全局变量),那么它们看起来不同也就不足为奇了。使用不同的方式完全没有问题。但我建议尽可能避免使用全局变量。 - Bergi
2个回答

2
创建一个实用程序模块(类似于您的HelpersModule):
const HelpersModule = {
  byId: id => document.getElementById(id),
  byTag: tag => Array.from(document.getElementsByTagName(tag))
};

...并且在你的其他代码中,将你需要的帮助函数分配给一个本地变量:

// ...
const byId = HelpersModule.byId; // if you only need 'byId'
const element = byId('my-id');
// ...

或者,使用解构:
const { byId } = HelpersModule; // if you only need 'byId'
const element = byId('my-id');

或者
const { byId, byTag } = HelpersModule; // if you need both
const element = byId('my-id');
const allSpans = byTag('span');

这是正确的想法,但他没有表明他正在使用ECMAScript 6。 - Dave Cousineau
@Sahuagin,加油,const 全球支持率达到 96.94%,而且我提供了一种解构的替代方法。如果 OP 真的遇到了 const 的问题,他可以轻松地用 var 来替换它。这是 downvote 的原因吗? - PeterMader
没有问题,答案在ES6中。你的解决方案真的很有帮助。谢谢。 - pastuszkam
我没有点踩。也许这并不重要,因为他没有指定版本。 - Dave Cousineau
我觉得在问题使用“传统JavaScript”语言表达,而回答却用现代的JavaScript风格写下来,这样的情况略显不协调。 - Dave Cousineau
@Sahuagin 我做了一些研究; 这个 问题已经有一年了,但社区的共识似乎是ES2015是可以接受的,但如果你使用了一些新功能,则可以留下说明。如果OP表示对ES2015满意,那么我将不会这样做,因为这样做可能是多余的。 - PeterMader

0

如果两个

var someElement = document.getElementById('id')

并且

var someElement = HelpersModule.byId('id');

如果要做同样的事情,我建议您只使用第一个模块而不是创建一个新模块。这样,您将保持对模块模型的忠实,并且每个模块只需要添加一行代码。创建一个全新的模块并仍然为每个模块编写一行代码是不必要的。这有帮助/我是否理解了您的问题?

编辑:

我现在明白你的意思了。您想知道是否应该创建一个单独的模块来保存每个模块的所有辅助方法。在这种情况下,最好仍然将辅助方法仅保留在需要它们的文件中。因此,如果您有一个仅在一个文件中使用且仅能用于该文件的辅助方法,则应将其保留在该文件中。如果它们在需要它们的文件中,那么更容易跟踪所有方法。这还可以防止您在文件之间跳来跳去以查找所需的方法。

因此,只需将辅助方法保留在需要它们的文件(调用它们的文件)中,而不是另一个模块中。当您的文件有数千行代码时,这会变得混乱。


当然,在这个例子中,为了一个函数创建另一个模块是没有意义的,我同意。但这只是一个例子。如果我有很多辅助函数,我可能需要这样的模块来管理它们。 - pastuszkam
我对我的回答进行了编辑,请告诉我是否有意义。谢谢 @pastuszkam - demogorgon
在这种方法中,我可能需要在每个需要这些函数的文件中复制一些函数的代码。我想避免任何重复。 - pastuszkam
@pastuszkam 如果你要在多个文件中复制它,那么是的,一个新文件来保存它们将使你的代码保持DRY(不要重复自己)。 - demogorgon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接