注意: 在维基百科上只一些内容只适合0.12以前的版本. 0.13以后的更多的官方文档, 请看http://docs.nwjs.io。
不同的基于webkit的窗口有不同的JavaScript 上下文环境, 比如:每个窗口都有自己的全局对象和一套自己的全局构造函数(例如 数组或对象)。
这是一些在Web浏览器中的常规做法。这是一件好事, 因为:
当某个对象的原型被一些库替换或扩充时 (例如 Prototype) 或一个简单的脚本,类似的其他窗口中的对象不受影响;
当一个程序员犯了错误(例如missing
new
before a poorly written constructor) 并且这个错误影响了全局作用域, 它仍然不会有太大的影响(一系列的窗口);恶意应用程序不能访问机密数据结构在其他窗口.
如果模块是通过应用的 manifest 文件的 "node-main"
属性进行指定的,那么模块将运行在 Node 上下文,但是之后就可以访问 window
对象. (详情请看文章 “node-main” )
Node 上下文的特性和限制
运行在 Node 上下文的脚本可以使用 __dirname
变量来获取其所在的目录。
Node.js global
对象是在 Node 上下文中的全局对象。任何 WebKit 窗口的 windows 对象并非全局,甚至在 Node 的上下文是隐式的(唯一的例外是 node-main ),例如,当你需要访问 windows 对象时,你必须(显式的)传递 windows 对象给你的模块函数。
解决其他脚本的相对路径问题
在WebKit中相对路径是根据主HTML文件路径来解析的 (像所有的浏览器一样)。相对路径在node的模块中是根据当前模块的位置来解析的 (像node.js一直是这样做的)。 只要记住你是在哪个上下文环境中。
例如,如果我们有文件 /myApp/main.html
:
<html><head><!-- will be resolved according to this html file path --><scriptsrc="components/myComponent.js"></script></head><body><script>// will be resolved according to this html file pathvar hello = require('./libs/myLib'); // __dirname is not defined in webkit context, this is only node.js thingconsole.log(__dirname); // undefined</script></body></html>
工作在不同的上下文
使用不同的上下文当然是有好处的,但是有时候也会让你的代码出现一些问题,因此需要一些相应的解决办法。
这种问题最常见的原因是 JavaScript 的 instanceof 操作符的行为导致。你在 MDN 应该能看到的 someValue instanceof someConstructor
这样的测试会在其原型链中存在 prototype 属性。但是,如果 someValue 是来自不同 JavaScript 上下文时,这样它就有其祖先对象,这样 someValue instanceof someConstructor
的检查操作就会不可避免的失败。
有几种方法可以解决这个问题。
避免使用instanceof
防止上下文相关的问题的最简单方法是避免使用instanceof当一个值可能来自另一个JavaScript上下文的时候. 例如, 你也许会使用 Array.isArray
来检查一个值是否为一个数组, 并且这个方法运行在一个可靠的上下文环境中。
然而, 如果这样一个方便的替代方法不是现成的, 或者当你面对的是别人的又问题的代码的时候(不是自己的),这个时候可能会是一个麻烦, 另一个解决方案是必要的。
使用来自其它上下文的构造函数
它抛出了这些错误 Error: First argument to waterfall must be an array of functions
(错误的认为它不是一个数组)。
使用 nwglobal
模块, 你可以访问到Node上下文环境中的 Array的构造函数,然后像下面这样重写它
:
require('async').waterfall( require('nwglobal').Array(
function(callback){
console.log('1.');
callback(null, 'one', 'two');
},
function(arg1, arg2, callback){
console.log('2.');
callback(null, 'three');
},
function(arg1, callback){
console.log('3.');
callback(null, 'done');
}
), function (err, result) {
console.log('Fin.');
if( err ) throw err;
console.log(result);
});