一尘不染

环境检测:node.js或浏览器

node.js

我正在开发一个需要同时在客户端和服务器端工作的JS-app(在浏览器中的Javascript和Node.js中),并且我希望能够重用部分代码。用于双方。

我发现这window是一个只能在浏览器和global节点上访问的变量,因此我可以检测代码在哪个环境中执行(假设没有脚本声明该window变量)

他们是两个问题。

  1. 我应该如何检测代码在哪个浏览器中运行。例如,此代码是否可以。(此代码是内联代码,这意味着它被一些全局代码包围,可在两种环境中重复使用)

    if window?
    totalPath= "../examples/#{path}"
    

    else
    totalPath= “../../examples/#{path}”

  2. 如何在两种环境中使用全局变量?现在,我正在执行以下操作,但这确实感觉不对。

        if window?
        window.DocUtils = {}
        window.docX = []
        window.docXData= []
    else
        global.DocUtils= {}
        global.docX = []
        global.docXData = []

阅读 408

收藏
2020-07-07

共1个答案

一尘不染

注意:这个问题有两个部分,但是因为标题是“环境检测:node.js或浏览器”-我将首先进入这一部分,因为我想很多人都会来这里寻求答案。
可能有一个单独的问题。

在JavaScript中,变量可以由内部作用域重新定义,因此,假设环境尚未创建名为process,global或window的变量,则很容易失败,例如,如果使用的是node.js
jsdom模块,则该API使用示例将

var window = doc.defaultView;

此后,window在该范围内运行的任何模块都将基于变量的存在检测环境会系统地失败。使用相同的逻辑,任何基于浏览器的代码都可以轻松覆盖globalprocess,因为它们不是该环境中的保留变量。

幸运的是,有一种方法需要全局范围并测试它的含义-如果使用new Function()构造函数创建新函数,则的执行范围将this绑定到全局范围,并且可以将全局范围直接与期望值进行比较。*)

因此,要创建一个函数,请检查全局范围是否为“ window”

var isBrowser=new Function("try {return this===window;}catch(e){ return false;}");

// tests if global scope is binded to window
if(isBrowser()) console.log("running under browser");

测试全局sope是否绑定到“ global”的函数将是

var isNode=new Function("try {return this===global;}catch(e){return false;}");

// tests if global scope is binded to "global"
if(isNode()) console.log("running under node.js");

try … catch -part将确保如果未定义变量,false则返回该变量。

isNode()还可以比较this.process.title==="node"或其他一些全球范围内可变发现里面的node.js如果你愿意,但相较于全球应该在实践中是不够的。

http://jsfiddle.net/p6yedbqk/

注意 :不建议检测运行环境。但是,它在特定的环境(例如具有全球范围内某些已知特征的开发和测试环境)中很有用。

现在-答案的第二部分。 在完成环境检测之后,您可以选择要使用的基于环境的策略(如果有)将“全局”变量绑定到应用程序。

我认为,这里推荐的策略是使用单例模式将您的设置绑定到类中。SO中已经有很多替代方案

在JavaScript中实现单例的最简单/最简洁的方法?

因此,事实证明,如果您不需要“全局”变量,并且根本不需要环境检测,只需使用单例模式定义一个模块即可为您存储值。好的,可以说模块本身是一个全局变量,实际上在JavaScript中是全局变量,但是至少从理论上讲,它看起来更干净一些。

*)https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function

注意:使用Function构造函数创建的函数不会创建其创建上下文的闭包。它们总是在全局范围内创建。运行它们时,它们将只能访问自己的局部变量和全局变量,而不能访问调用Function构造函数的作用域中的局部变量和全局变量。

2020-07-07