UMD模式中的全局上下文 [英] Global context inside UMD pattern

查看:329
本文介绍了UMD模式中的全局上下文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个不可知的日志记录机制,它在浏览器和nodejs中运行(例如,nodejs中缺少console.debug)。

I am writing an agnostic logging mechanism that works inside the browser and in nodejs (e.g. console.debug is missing in nodejs).

// 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;
});

我偶然发现了两个不能解释的差异:

I stumbled upon 2 differences I cannot explain:


  1. 正如预期的那样,对于浏览器案例,变量global具有window的值。但是,Nodejs的global只是一个简单的对象,而不是Nodejs的全局变量。这是有意的吗?可以使用'.call'来执行模块,以保留浏览器和Nodejs的相应上下文。由于这是一种常见的UMD模式,我怀疑在Nodejs中修改全局变量是不是一个坏主意,这让我接下来的问题。

  1. As expected, for the browser case the variable 'global' has the value of window. However, with Nodejs 'global' is just a simple object and not the global variable of Nodejs. Is this intended? One could execute the module using '.call' to preserve the corresponding context for the browser and Nodejs. As this is a common accepted UMD pattern, I was doubting if it is a bad idea to modify the global variable in Nodejs, which takes me to next question.

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

Inside the browser it is possible to overwrite the global console function by passing over my custom object to the console property. One could have back the old behaviour by restoring the reference to the original object. This is not possible in Nodejs, it fails when I am trying to pass my own logger object to global.console. Strange enough, that I did not find any useful documentation in the web...

希望得到一些澄清!

推荐答案

更新

显然是以下内容可能无法在Chrome中的所有情况下使用。请参阅此答案的评论。

Apparently the following may not work in all situations in Chrome. See the comments to this answer.

原创回答

我在我的代码中使用以下代替 this 来获取全局对象。在ECMAScript 3和5环境中似乎不漏水:

I'm using the following instead of this in my code to get the global object. It seems watertight in ECMAScript 3 and 5 environments:

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

这是为了安抚短语,例如JSLint,这有点间接,不喜欢使用 eval 函数构造函数。如果你不关心这些事情(对你而言),你可以使用以下更简单的代码:

This is a little indirect in an effort to appease linters, such as JSLint, that don't like use of eval and the Function constructor. If you don't care about such things (yay for you), you can use the following simpler code instead:

Function("return this")()

背景:

  • https://stackoverflow.com/a/7341755/96100
  • How to get the global object in JavaScript?

这篇关于UMD模式中的全局上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆