相对于简单的闭包,模块级状态的缺点是什么?

问题描述 投票:0回答:1

我一直觉得模块级状态mutable-variables不好,很丑,但我解释不了 何以. 下面是我说的一个模块的例子。

// module with top level state
let book = null;

export function init() {
  book = { 
    name: 'a good book', 
    author: 'me'
  }
}

export function rest() {
  book = null;
}

export function fetchBook() {
  fetch('/book').then(b => book = b)
}

export function get() {
  return book;
}

vs

// module with closure
export default function() {
  let book = null;
  return {
    init: () => { /* same as module */ },
    reset: () => { /* same as module */ },
    fetchBook: () => { /* same as module */ },
    get: () => { /* same as module */ }
  }
}

我看到的唯一区别是由于模块只解析了一次,所以模块级状态类似于 "单体",但闭合的可以多次实例化,他们有自己的状态版本。模块级状态还有哪些优点?

javascript module closures state
1个回答
1
投票

普通JS

当使用commonJS或任何捆绑程序(webpackrollup)时,模块通过封装成一个闭包来执行,通过 require, module等作为参数,并执行这个函数(对每一个 require). 所以最后,归根结底是一样的。所以,是否使用模块变量归根结底是个人喜好的问题,至少对commonJS来说是这样。

(参见nodejs加载cjs模块的实现方式 此处)

ES模块

ES模块带来的制动变化。

// module.mjs

export let string = "not done";

setTimeout(() => {
    res("done");
}, 1000);


// main.mjs

import { string } from "./module.mjs";

console.log(string); // "not done"

setTimeout(() => {
    console.log(string); // "done"
}, 2000);

已命名的ES模块出口可以通过以下方式重新分配。输出 模块。这使得模块的行为更像对象而不是闭包。这到底是好事还是坏事,你得自己决定。

警告

使用 importexport 意味着您使用的是ES模块!Babel模块和Typescript使用相同的importexport语法,但在外壳下移植到commonJS。Babel Modules和Typescript使用相同的importexport语法,但在外壳下移植到commonJS。你可以用Typescript或Babel来运行ES Modules的例子,但会得到不同的结果,因为在启用ES Modules的情况下,用nodejs来运行它。

我的2分钱

只有当你知道自己在做什么,并且意识到其中的含义时,才能使用模块变量。这就像平等与严格平等一样。

© www.soinside.com 2019 - 2024. All rights reserved.