关于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很相似


3 回复

关于Nodejs的作用域

在前端的JavaScript中,我们通常不会直接把变量暴露在全局作用域中。例如,在使用jQuery时,我们会通过一个匿名函数来封装私有变量,从而避免污染全局命名空间。这种方式不仅有助于保持代码的整洁,还能避免潜在的冲突。

示例代码

(function(w, u) {
    var something = "This is private";
    w.$ = something;
})(window, undefined);

这段代码定义了一个立即执行的匿名函数,并将全局对象 windowundefined 作为参数传入。这样,变量 something 就不会泄露到全局作用域中,只有 $ 对象会被暴露出去。

在Node.js中的作用域

在Node.js中,作用域的概念与前端JavaScript有所不同。Node.js中模块化的设计使得每个文件(模块)都有自己的作用域,外部无法直接访问内部的变量。这种设计有助于组织代码并减少全局变量的使用。

示例代码

假设我们有两个文件:app.jsmodule.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 中,我们定义了一些内部变量 inModulefromAppjs,并通过 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.jsmodule.js 是两个独立的文件,但它们可以通过 requireexports 进行交互。这种方式确保了每个模块的作用域是私有的,从而减少了全局变量的使用和潜在的冲突。


果然还是看不懂… 我理解的话, 模块化就是为了将大问题分解成想不相干的小问题, 模块和模块不能直接相互访问很正常吧

在Node.js中,作用域的理解与前端JavaScript有所不同。特别是在模块化和异步编程方面,这可能让初学者感到困惑。以下是一些关于Node.js作用域的基本要点和示例代码,帮助你更好地理解。

1. 模块作用域

在Node.js中,每个模块都有自己的作用域。这意味着,在一个模块中定义的变量、函数等,默认情况下在其他模块中是不可见的。为了在不同模块之间共享数据,通常使用exportsrequire来实现。

示例代码

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中的作用域和模块化概念。

回到顶部