关于Nodejs的作用域,写一点点东西,大牛自觉略过
关于Nodejs的作用域,写一点点东西,大牛自觉略过
在前端的JavaScript中,我们都不会把变量暴露在全局,比如jQuery,在全局只注册了一个$对象. 众所周知我们都会用匿名函数把私有变量限制在一个私有作用域,必要时才会在全局注册一个对象,比如jQuery的思路
(function(w,u){
//var something and function something
w.$=someObject;
})(window,undefined);
但在Node.js中,对于我这样的初学者,关于作用域的说明实在有点少,比如模块化的概念,令初学者对整个app的作用域逻辑感觉混乱,且别说Callback和和异步编程思路.还有就是运行了Node后没有类似Chrome的Console,这个是最晕的,比如检查一下究竟变量有没暴露在全局.好在有repl,这些问题都得以解决.
首先,我会想象Node.js运行一个app.js,都会用匿名函数把整个App.js的代码私有化,除非在代码中显式地申明(或是没有var)这个是全局对象(废话),当然我们不用自己写这个匿名函数,或者说运行Node app.js时,可以理解成app.js()
其次,module间的变量/对象是不可见的,只能够通过exports传递,就是说,我们不能把模块理解成app.js这个匿名函数里创建的一个对象(函数也是对象).
/**
* Created with JetBrains WebStorm.
* User: BiG
* Date: 5/13/13
* Time: 6:06 PM
* To change this template use File | Settings | File Templates.
*/
//this is app.js
global.globalApp = 'this is global var';
var appjsVar = "this is from app";
exports.outAppjs = appjsVar; //如果把这句写在require后,module将得不到outAppjs
var modulejs = require('./module'),
modulejsDo = modulejs.doSome(2),
repl = require('repl');
console.log(appjsVar);
console.log(globalApp);
console.log(modulejs.fromModule);
console.log(modulejsDo);
console.log(modulejs.backToAppjs);
repl.start(’>’);
//this is module.js
var inModule = “this is from module”,
fromAppjs = require(’./app’);
exports.fromModule = inModule;
exports.doSome = function (e) {
var a, b, c;
a = b = e;
c = ‘this is from module.dosome,and the result is ’ + (a + b);
return c;
};
exports.backToAppjs = fromAppjs.outAppjs + ’ WARN:is is from appjs to module,and back to appjs’;
其实无论app.js,还是module.js,其作用域全部是私有的…我在app.js的局部变量想让module.js知道,我只能通过exports传过去,而且必须把export写在require前,否则require了,变量其实还没过去…
以下是结果
this is from app
this is global var
this is from module
this is from module.dosome,and the result is 4
this is from app WARN:is is from appjs to module,and back to appjs
>
感谢repl哈哈,这种方式和Chrome很相似
关于Nodejs的作用域
在前端的JavaScript中,我们通常不会直接把变量暴露在全局作用域中。例如,在使用jQuery时,我们会通过一个匿名函数来封装私有变量,从而避免污染全局命名空间。这种方式不仅有助于保持代码的整洁,还能避免潜在的冲突。
示例代码
(function(w, u) {
var something = "This is private";
w.$ = something;
})(window, undefined);
这段代码定义了一个立即执行的匿名函数,并将全局对象 window
和 undefined
作为参数传入。这样,变量 something
就不会泄露到全局作用域中,只有 $
对象会被暴露出去。
在Node.js中的作用域
在Node.js中,作用域的概念与前端JavaScript有所不同。Node.js中模块化的设计使得每个文件(模块)都有自己的作用域,外部无法直接访问内部的变量。这种设计有助于组织代码并减少全局变量的使用。
示例代码
假设我们有两个文件:app.js
和 module.js
。我们来看看它们是如何交互的。
app.js
global.globalApp = 'this is global var';
var appjsVar = "this is from app";
// 必须在require之前导出变量
exports.outAppjs = appjsVar;
var modulejs = require('./module'),
modulejsDo = modulejs.doSome(2),
repl = require('repl');
console.log(appjsVar);
console.log(globalApp);
console.log(modulejs.fromModule);
console.log(modulejsDo);
console.log(modulejs.backToAppjs);
repl.start('>');
module.js
var inModule = "this is from module",
fromAppjs = require('./app');
exports.fromModule = inModule;
exports.doSome = function(e) {
var a, b, c;
a = b = e;
c = 'this is from module.dosome, and the result is ' + (a + b);
return c;
};
exports.backToAppjs = fromAppjs.outAppjs + ' WARN: is it from appjs to module, and back to appjs';
解释
- 全局变量:在
app.js
中,我们声明了一个全局变量globalApp
。 - 模块导出:在
app.js
中,我们通过exports
导出了一个变量outAppjs
。 - 模块导入:在
app.js
中,我们使用require
导入了module.js
中的模块,并调用了doSome
方法。 - 模块内部变量:在
module.js
中,我们定义了一些内部变量inModule
和fromAppjs
,并通过exports
导出了需要对外公开的部分。
运行结果
this is from app
this is global var
this is from module
this is from module.dosome, and the result is 4
this is from app WARN: is it from appjs to module, and back to appjs
>
从上面的结果可以看出,虽然 app.js
和 module.js
是两个独立的文件,但它们可以通过 require
和 exports
进行交互。这种方式确保了每个模块的作用域是私有的,从而减少了全局变量的使用和潜在的冲突。
果然还是看不懂… 我理解的话, 模块化就是为了将大问题分解成想不相干的小问题, 模块和模块不能直接相互访问很正常吧
在Node.js中,作用域的理解与前端JavaScript有所不同。特别是在模块化和异步编程方面,这可能让初学者感到困惑。以下是一些关于Node.js作用域的基本要点和示例代码,帮助你更好地理解。
1. 模块作用域
在Node.js中,每个模块都有自己的作用域。这意味着,在一个模块中定义的变量、函数等,默认情况下在其他模块中是不可见的。为了在不同模块之间共享数据,通常使用exports
和require
来实现。
示例代码
app.js
global.globalApp = 'this is global var';
var appjsVar = "this is from app";
exports.outAppjs = appjsVar;
var modulejs = require('./module');
var modulejsDo = modulejs.doSome(2);
console.log(appjsVar); // 输出: this is from app
console.log(globalApp); // 输出: this is global var
console.log(modulejs.fromModule); // 输出: this is from module
console.log(modulejsDo); // 输出: this is from module.dosome,and the result is 4
module.js
var inModule = "this is from module";
exports.fromModule = inModule;
exports.doSome = function(e) {
var a, b, c;
a = b = e;
c = 'this is from module.dosome,and the result is ' + (a + b);
return c;
};
exports.backToAppjs = require('./app').outAppjs + ' WARN:is is from appjs to module,and back to appjs';
2. 全局变量
在Node.js中,可以使用global
对象来声明全局变量。这些变量可以在任何模块中访问。
3. 异步编程
在Node.js中,异步编程是常见的模式,例如使用回调函数或Promise。虽然这与作用域无关,但理解这一点有助于编写高效和可维护的代码。
4. 使用REPL调试
由于Node.js没有类似于Chrome浏览器的控制台,可以使用Node.js的REPL(Read-Eval-Print Loop)来进行交互式调试。
示例
node
> console.log(global.globalApp);
this is global var
>
通过上述示例代码和解释,希望你能更好地理解Node.js中的作用域和模块化概念。