【问题标题】:Global context inside UMD patternUMD 模式中的全局上下文
【发布时间】:2014-05-23 16:49:04
【问题描述】:

我正在编写一个在浏览器和 nodejs 中工作的不可知日志机制(例如 nodejs 中缺少 console.debug)。

// UMD with no dependencies
(function(global, factory) {
    if (typeof module === 'object') {        
        module.exports = factory();

        // GLOBAL IS NOT WHAT I WOULD EXPECT, YOU?
        global.console = factory();

    } else if (typeof define === 'function' && define.amd) {
        define(factory);
    } else {
        global.console = factory();
    }
})(this, function() {
    function logger() {};
    return logger;
});

我偶然发现了两个我无法解释的差异:

  1. 正如预期的那样,对于浏览器情况,变量“global”的值是 window。但是,对于 Nodejs,“全局”只是一个简单的对象,而不是 Nodejs 的全局变量。这是故意的吗?可以使用“.call”执行该模块,以保留浏览器和 Nodejs 的相应上下文。由于这是一种普遍接受的 UMD 模式,我怀疑在 Nodejs 中修改全局变量是否是一个坏主意,这将我带到下一个问题。

  2. 在浏览器中,可以通过将我的自定义对象传递给控制台属性来覆盖全局控制台功能。可以通过恢复对原始对象的引用来恢复旧行为。这在 Nodejs 中是不可能的,当我尝试将自己的记录器对象传递给 global.console 时它会失败。奇怪的是,我在网上没有找到任何有用的文档......

希望得到一些澄清!

【问题讨论】:

  • 好问题。这真是一场闹剧。

标签: javascript node.js console global amd


【解决方案1】:

更新

显然,以下内容可能不适用于 Chrome 中的所有情况。见this answer的cmets。

原答案

我在我的代码中使用以下而不是this 来获取全局对象。在 ECMAScript 3 和 5 环境中似乎是无懈可击的:

(function(f) { return f("return this")(); })(Function)

为了安抚不喜欢使用 evalFunction 构造函数的 linter,例如 JSLint,这有点间接。如果您不关心这些事情(为您服务),您可以改用以下更简单的代码:

Function("return this")()

背景:

【讨论】:

  • linked to 的帖子中,有人在 cmets 中指出,毕竟它可能无法在所有环境中工作。 在 Chrome 中我得到:EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not a allowed source of script in the following Content Security Policy directive: "script-src 'self' 'unsafe-inline '"this answer,@Pat 评论)
猜你喜欢
  • 2018-09-06
  • 1970-01-01
  • 2016-08-24
  • 2021-02-15
  • 1970-01-01
  • 2018-02-15
  • 2014-01-08
  • 2023-03-17
  • 1970-01-01
相关资源
最近更新 更多