注意:这个问题有两个部分,但是因为标题是“环境检测:node.js或浏览器”-我将首先进入这一部分,因为我想很多人都会来这里寻求答案。 可能有一个单独的问题。
在JavaScript中,变量可以由内部作用域重新定义,因此,假设环境尚未创建名为process,global或window的变量,则很容易失败,例如,如果使用的是node.js jsdom模块,则API使用示例将
var window = doc.defaultView;
之后,基于isNode()
变量的存在来检测环境将被在该范围内运行的任何模块系统地失败。 使用相同的逻辑,任何基于浏览器的代码都可以轻松覆盖this.process.title==="node"
或process
,因为它们不是该环境中的保留变量。
幸运的是,有一种方法需要全局范围并测试它的含义-如果使用2755725326574683683136构造函数创建新函数,则this.process.title==="node"
的执行范围将绑定到全局范围,并且可以将全局范围直接与期望值进行比较 。 *)
因此,要创建一个函数,请检查全局范围是否为“ 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");
测试全局范围是否绑定到“全局”的函数为
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将确保如果未定义变量,则返回isNode()
。
如果愿意,isNode()
也可以比较this.process.title==="node"
或在node.js中找到的某些其他全局范围变量,但在实际中与全局比较就足够了。
[HTTP://JS fiddle.net/怕6也多半情况/]
注意:不建议检测运行环境。 但是,它在特定的环境(例如具有全球范围内某些已知特征的开发和测试环境)中很有用。
现在-答案的第二部分。 在完成环境检测之后,您可以选择要使用的基于环境的策略(如果有)将“全局”变量绑定到应用程序。
我认为,这里推荐的策略是使用单例模式将您的设置绑定到类中。 SO中已经有很多替代方案
在JavaScript中实现单例的最简单/最简洁的方法?
因此,事实证明,如果您不需要“全局”变量,并且根本不需要环境检测,只需使用单例模式定义一个模块即可为您存储值。 好的,可以说模块本身是一个全局变量,实际上在JavaScript中是全局变量,但至少在理论上,它看起来更干净一些。
*) [HTTPS://developer.Mozilla.org/恩-US/docs/Web/JavaScript/reference/global_objects/function]
注意:使用Function构造函数创建的函数不会创建 封闭其创作环境; 他们总是在 全球范围。 运行它们时,他们将只能访问 他们自己的局部变量和全局变量,而不是范围中的变量 在其中调用了Function构造函数。