NOTE: This question had two parts, but because the title was "Environment detection: node.js or browser" - I will get to this part first, because I guess many people are coming here to look for an answer to that. A separate question might be in order.
在JavaScript中,变量可以由内部作用域重新定义,因此假设环境没有创建名为process、global或window的变量,则很容易失败,例如,如果使用node.js jsdom模块,API usage example has
var window = doc.defaultView;
在此之后,基于window
个变量的存在来检测环境将被在该范围内运行的任何模块系统性地失败.使用相同的逻辑,任何基于浏览器的代码都可以轻松覆盖global
或process
,因为它们在该环境中不是保留变量.
幸运的是,有一种方法可以要求全局范围并测试它是什么——如果您使用new Function()
构造函数创建一个新函数,this
的执行范围将绑定到全局范围,您可以直接将全局范围与预期值进行比较.*)
因此,要创建一个函数判断全局范围是否为"窗口",需要
var isBrowser=new Function("try {return this===window;}catch(e){ return false;}");
// tests if global scope is bound 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 bound 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/
100: detecting the running environment is not recommended. However, it can be useful in a specific environment, like development and testing environment which has some known characteristics for the global scope.
Now - the second part of the answer.环境检测完成后,您可以 Select 要使用哪种基于环境的策略(如果有)将"全局"变量绑定到应用程序.
在我看来,这里推荐的策略是使用单例模式来绑定类内的设置.目前已经有一个很好的备选方案 list
Simplest/cleanest way to implement a singleton in JavaScript
因此,如果您不需要"全局"变量,也不需要环境检测,那么可以使用单例模式定义一个模块,该模块将为您存储值.好吧,我们可以说模块本身是一个全局变量,在JavaScript中它实际上是一个全局变量,但至少在理论上,它看起来更简洁.
*) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function
注意:使用函数构造函数创建的函数不会创建