【问题标题】:Pure Javascript Module Pattern in TypeScript to not mess up global scopeTypeScript 中的纯 Javascript 模块模式不会弄乱全局范围
【发布时间】:2018-08-21 22:00:32
【问题描述】:

我作为纯 javascript 的前端开发人员已经有一段时间了。 正如您在下面的示例中看到的那样,我已经习惯了模块模式。现在我从 TypeScript 开始,我不可能得到相同的示例模式。目标是获得一种命名空间,以免破坏全球范围。 在 TypeScript 中实现相同目标的最佳方法是什么?谢谢

var myModulePattern = (function(){
    // Private properties - more or less
        var 
            moduleName = "myModulePattern",
            moduleAuthor = "Bob"
        ;
    // Private Methods - more or less
        function sayModuleHello (){
            return "Module " + moduleName + " made by " + moduleAuthor;
        }

    return {
    // Public properties
        createYear : 2018,
    // Public Methods
        greeting: function(){
            console.log("Hi: "+sayModuleHello());
            
        }
    }
})();

// Exits an alone object literal, so is no possible create another instance of the "class"
// Really, this is like a namespace to not mess up the global scope
myModulePattern.greeting();
console.log(myModulePattern.createYear);

【问题讨论】:

  • 难道 ES6 模块不能满足你对模块化的所有需求吗?
  • 如果有人渴望模块模式的通用 TypeScript 实现(如 Crockford 所述),您可以看看这个:bit.ly/2J4kjNx

标签: javascript typescript design-patterns module


【解决方案1】:

这正是 namespaces 的用途。

namespace MyModule {
    // Private variables
    const moduleName = "myModulePattern";
    const moduleAuthor = "Bob";

    // Private functions
    function sayModuleHello() {
        return "Module " + moduleName + " made by " + moduleAuthor;
    }

    // Public properties
    export var createYear = 2018;
    // Public Methods
    export function greeting() {
        console.log("Hi: "+sayModuleHello());
    }
}

MyModule.greeting();
console.log(MyModule.createYear);

您可能还想将模块放在自己的文件中,这样您就不再需要 namespace 包装器了。

【讨论】:

  • 好答案。您也可以使用export const createYear 而不是var
  • @JamesMonger 是的,我想过,但原始代码中的对象属性是可变的,所以我保留了它。
  • @Bergi,非常感谢您的回答。这只是我一直在寻找的。但是我的 ts-lint 对命名空间发出警告。是否已弃用命名空间?
  • @Casares 我不知道。警告说什么?
  • @Bergi,它说:[ts-lint] 'namespace' and 'module' is disallowed (no-namespace. 这是 tslint.json 配置文件中的一条规则,用于我的开发环境中的 linter (与代码相比)。如果我继续并且 ts 被编译并抛出 adecuate js,那么一切正常。我的关注是如果命名空间在当今被认为是好的做法,或者它在类型脚本 2.7 中被弃用。谢谢
【解决方案2】:

我建议您使用 typescript 类,如文档 https://www.typescriptlang.org/docs/handbook/classes.html 中所述

class myClassPattern {
    private className: string;
    private classAuthor: string;

    constructor(name: string, author: string) {
        this.className = name;
        this.classAuthor = author;

    }
    private sayClassHello():string{
      return "Class " + this.className + " made by " + this.classAuthor;
    }
    public greeting() {
        console.log("Hi: "+ this.sayClassHello());
    }
}

let greeter = new myClassPattern("myClassName", "myName");
greeter.greeting();

【讨论】:

  • 为什么推荐class? OP 不需要多个实例。
  • 这是一个糟糕的建议。类几乎在所有方面都较差,除了在创建相同类型的多个实例时节省内存。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-14
  • 2016-06-06
  • 1970-01-01
  • 2013-11-28
  • 2015-11-01
相关资源
最近更新 更多