【问题标题】:es5 modular design pattern to es6es5 模块化设计模式到 es6
【发布时间】:2018-01-08 14:14:43
【问题描述】:

我有一个每天有 10 万用户的网站。目前我们正在使用模块化设计模式在 Jquery/Vanilla JS 中编写代码。一个简单的隐藏/显示加载器的js如下

"use strict";
var loaderHandler = (function(){
    var loader = document.getElementById('main_loader');
    return{
        showProcessLoader : function(){
            loader.style.display = 'block';
            loader.style.opacity = '0.5';
        },
        hideLoader : function(){
            loader.style.display = 'none';
        }
    }
})();
docReady(function() {
    loaderHandler.hideLoader();

});

每当我想在某个地方显示加载器时,我只需调用 loaderHandler.showProcessLoader();和 loaderHandler.hideLoader();隐藏它。同样,我还有其他使用相同设计模式编写的 JS 文件,我使用来自该页面所需的所有 js 的 gulp 任务创建了一个缩小的 JS。目前,一切正常,我可以毫无问题地在另一个内部调用一个 js 文件函数。

我决定将我的应用程序迁移到最新的 es6 现在我有以下问题/查询

  1. 什么是 es6 中的设计模式,它将等同于我的模块化设计模式?

  2. 我不打算重写我现有的 js 文件,而是只在 es6 中编写新的 js。所以我希望新的设计模式不应该干扰现有的架构,并且仍然支持我在 es6 中编写新的 js 文件。

  3. 另外,当为页面创建单个缩小文件时,我仍然应该能够轻松地调用另一个 js 文件函数。

编辑 - 我已经在使用 babel 将我的 es6 代码转换为 es5 等效代码

【问题讨论】:

  • 看起来您使用模块模式的原因是为了隐私(例如,变量 loader 将是 loaderHandler 函数的私有)。 ES6 实际上并没有提供更好的模块模式,所以如果你需要严格的隐私,你应该继续做你正在做的事情。

标签: javascript jquery design-patterns ecmascript-6


【解决方案1】:

1) es6 中的设计模式是什么,相当于我的模块化设计模式?

设计模式不一定内置于语言中,它们只是一种语言可能提供也可能不提供足够抽象能力来完成的技术。根据问题 2,您似乎知道,您可以在 ES6 中执行之前可以执行的任何设计模式,反之亦然。事实上,像 babel 这样的转译器会在 es6 中写入代码,然后像魔术一样将其转换为以前的版本。

但实际上,您似乎渴望使用 ES6 中提供的一些最新功能,并且根据您上面的代码,您似乎需要某种类型的私有变量和方法封装,这意味着 classes可能非常适合您。

转换它非常简单,但您唯一需要记住的是,与使用 IIFE 相比,您需要导出类的新实例。如果您想要或什至进行一些继承,您还可以获得类的多个实例的能力,但是对于您当前的示例,这些功能可能不是一个很好的用例。

在下面的示例中,元素的 id 被传递给构造函数,这意味着如果您选择或简单地导出单例实例,您可以将此类重新用于任意数量的元素。

class AbstractLoaderHandler{
  constructor(el_id){
    this.loader = document.getElementById(el_id)
  }
  
  showProcessLoader(){
    this.loader.style.display = 'block';
    this.loader.style.opacity = '0.5';
  }
  
  hideLoader(){
    this.loader.style.display = 'none';
  }
}

let loaderHandler = new AbstractLoaderHandler('main_loader');

loaderHandler.hideLoader();
<div id="main_loader">Hello World</div>
<button onClick="loaderHandler.showProcessLoader()">Show</button> 
<button onclick="loaderHandler.hideLoader()">Hide</button>

3) 此外,当为页面创建单个缩小文件时,我仍然应该能够轻松地调用另一个 js 文件函数。

请记住,这完全与您捆绑文件的方式有关。您真正需要做的就是确保将您创建的任何内容作为全局变量公开。

【讨论】:

  • "您似乎需要某种类型的私有变量和方法封装,这意味着类可能非常适合您" - 不。他正在寻找 ES6 模块。 only 如果您需要创建多个实例的能力,则应该使用类,否则绝对是零优势。特别是,编写一个类只是为了实例化一个单例并导出一个反模式。
  • @Bergi 除了 ES6 模块还没有在任何浏览器中本地实现,你需要一个转译器/捆绑器组合来让它们工作,OP 说他们不想干扰他们现有的建筑学。至于它是一种反模式,那是基于意见的,因为这里有一篇似乎不同意你的文章:medium.com/@dmnsgn/singleton-pattern-in-es6-d2d021d150ae
  • 现代浏览器确实原生支持 ES6 模块,但即使它们不支持,模块捆绑器也不需要干扰 OP 现有代码。关于中篇文章,即使在那里,作者也指出单例是众所周知的,但他喜欢尝试 ES6 类。
  • 可靠的答案(除了类 ref),他现在已经编辑了它 - 那么为什么要投反对票呢? +1
  • @Bergi 模块捆绑器肯定会影响 OP 的代码,因为他需要在他之前编写的所有代码中开始使用导出和导入语句。 OP 似乎正在使用 grunt 来简单地连接文件,这使得在他的基于 IIFE 的模块之外定义的所有变量都被定义为全局定义,而捆绑器会正确地封装它。类只是封装变量和方法的一种不同方式,我想说它的一个优点是,在我看来,它更容易理解,但您可能不同意。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-21
  • 2016-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多