在某些情况下执行node程序的过程中,我们可能希望给node传递一些参数:
node index.js env=development xiaoming
我们可以通过process内置对象中获取参数,如果我们直接打印这个内置对象,它里面包含很多信息,比如版本、操作系统等。
process { version: 'v14.15.0', versions: { node: '14.15.0', v8: '8.4.371.19-node.17', uv: '1.40.0', zlib: '1.2.11', brotli: '1.0.9', ares: '1.16.1', modules: '83', nghttp2: '1.41.0', napi: '7', llhttp: '2.1.3', openssl: '1.1.1g', cldr: '37.0', icu: '67.1', tz: '2020a', unicode: '13.0' }, arch: 'x64', platform: 'win32', release: { name: 'node', lts: 'Fermium', sourceUrl: 'https://nodejs.org/download/release/v14.15.0/node-v14.15.0.tar.gz', headersUrl: 'https://nodejs.org/download/release/v14.15.0/node-v14.15.0-headers.tar.gz', libUrl: 'https://nodejs.org/download/release/v14.15.0/win-x64/node.lib' }, _rawDebug: [Function: _rawDebug], moduleLoadList: [ 'Internal Binding stream_wrap', 'Internal Binding tcp_wrap', 'Internal Binding pipe_wrap', 'NativeModule internal/stream_base_commons', ... 9 more items ], binding: [Function: binding], _linkedBinding: [Function: _linkedBinding], _events: [Object: null prototype] { newListener: [Function: startListeningIfSignal], removeListener: [Function: stopListeningIfSignal], warning: [Function: onWarning], SIGWINCH: [Function (anonymous)] }, _eventsCount: 4, _maxListeners: undefined, domain: null, _exiting: false, config: { target_defaults: { cflags: [], default_configuration: 'Release', defines: [], include_dirs: [], libraries: [] }, variables: { asan: 0, build_v8_with_gn: false, coverage: false, v8_trace_maps: 0, v8_use_siphash: 1, want_separate_host_toolset: 0 } }, dlopen: [Function: dlopen], uptime: [Function: uptime], _getActiveRequests: [Function: _getActiveRequests], _getActiveHandles: [Function: _getActiveHandles], reallyExit: [Function: reallyExit], _kill: [Function: _kill], hrtime: [Function: hrtime] { bigint: [Function: hrtimeBigInt] }, cpuUsage: [Function: cpuUsage], resourceUsage: [Function: resourceUsage], memoryUsage: [Function: memoryUsage], kill: [Function: kill], exit: [Function: exit], openStdin: [Function (anonymous)], allowedNodeEnvironmentFlags: [Getter/Setter], assert: [Function: deprecated], features: { inspector: true, debug: false, uv: true, ipv6: true, tls_alpn: true, tls_sni: true, tls_ocsp: true, tls: true, cached_builtins: true }, _fatalException: [Function (anonymous)], setUncaughtExceptionCaptureCallback: [Function: setUncaughtExceptionCaptureCallback], hasUncaughtExceptionCaptureCallback: [Function: hasUncaughtExceptionCaptureCallback], emitWarning: [Function: emitWarning], nextTick: [Function: nextTick], _tickCallback: [Function: runNextTicks], _debugProcess: [Function: _debugProcess], _debugEnd: [Function: _debugEnd], _startProfilerIdleNotifier: [Function (anonymous)], _stopProfilerIdleNotifier: [Function (anonymous)], stdout: [Getter], stdin: [Getter], stderr: [Getter], abort: [Function: abort], umask: [Function: wrappedUmask], chdir: [Function: wrappedChdir], cwd: [Function: wrappedCwd], env: { ALLUSERSPROFILE: 'C:\\ProgramData', APPDATA: 'C:\\Users\\hp\\AppData\\Roaming', }, title: 'C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe', argv: [ 'D:\\nodejs\\node.exe', 'D:\\qdcode\\node.js\\node传递参数\\01-dome.js' ], execArgv: [], pid: 14472, ppid: 18452, execPath: 'D:\\nodejs\\node.exe', debugPort: 9229, argv0: 'D:\\nodejs\\node.exe', _preload_modules: [], mainModule: Module { id: '.', path: 'D:\\qdcode\\node.js\\node传递参数', exports: {}, parent: null, filename: 'D:\\qdcode\\node.js\\node传递参数\\01-dome.js', loaded: false, children: [], paths: [ 'D:\\qdcode\\node.js\\node传递参数\\node_modules', 'D:\\qdcode\\node.js\\node_modules', 'D:\\qdcode\\node_modules', 'D:\\node_modules' ] }, [Symbol(kCapture)]: false }
找到其中的argv属性:我们发现他是一个数组,里面包含我们传递的参数。
console.log(process.argv);
[ 'D:\\nodejs\\node.exe', 'D:\\qdcode\\node.js\\node传递参数\\01-dome.js', 'env=development', 'xiaoming' ]
Node中给我们提供了一些全局对象,方便我们进行一些操作
其中有一些特殊的全局变量,这些全局对象实际上是模块中的变量,只是每个模块都有,看起来像是全局变量;
但是在命令交互中是不可以使用的;
包括:__dirname、__filename、exports、module、require()
__dirname:获取当前文件所在的路径(不包括后面的文件名)
__filename:获取当前文件所在的路径和文件名称(包括后面的文件名称)
console.log(__dirname); //D:\qdcode\node.js\node传递参数 console.log(__filename); //D:\qdcode\node.js\node传递参数\01-dome.js
process对象:提供了Node进程中相关的信息:
console对象:提供了简单的调试控制台
定时器参数:在Node中使用定时器有好几种方式:
在浏览器中,全局变量都是window上的,比如document、setInterval、alert、console等。
在Node中也有一个global属性,看起来它里面也有很多其他对象。
但是在浏览器中执行js代码,如果我们在顶级范围内通过var定义一个属性,默认会被添加到window对象上
var name = 'zhangsan' console.log(window.name) //zhangsan
但是在node中,我们通过var定义一个变量,他只是当前模块中有一个变量,不会放到全局中
var name = 'zhangsan' console.log(window.name) //undefined
事实上模块化开发最终目标是将程序划分成一个个小的结构,这个结构中编写属于自己的逻辑代码,有自己的作用域,不会影响到其他的结构。
这个结构可以将自己希望暴露的变量、函数、对象导出给其他结构使用。
也可以通过某种方法,导入另外结构中的变量、函数、对象等。
上面提到的结构就是模块;安装这种那个结构划分开发程序的过程,就是模块化开发的过程。
模块化已经是js一个非常迫切的需求:
小明编写的xiaoming.js
var name = '小明'
小红编写的xiaohong.js也使用的name
var name = '小红'
小明又在sayName.js中调用了name变量
console.log(name);
这样的顺序引入js会导致小明的代码被小红的代码覆盖。从而输出错误的信息。
<head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="./xiaoming.js"></script> <script src="./xiaohong.js"></script> <script src="./sayName.js"></script> </head>
这种情况我们可以采用立即执行函数结果(IIFE)
xiaoming.js
var xiaoming = (function(){ var name = 'xiaoming'; return{ name } })()
xiaohong.js
var xiaohong =(function(){ var name = 'xiaohong' return { name } })()
sayName.js
console.log(xiaoming.name); //xiaoming console.log(xiaohong.name); //xiaohong
使用立即执行函数我们不必关注js引入的顺序
但是这样也有新的问题:
我们需要知道CommonJS是一个规范,最初提出来是在浏览器以外的地方使用,并且当时被命名为ServerJS,后来为了体现它的广泛性,修改为CommentJS。
所以,Node中对CommentJS进行了支持和实现,让我们在开发node的过程中可以方便的进行模块化开发:
Bar.js 暴露方法和变量 可以通过module.exports和exports.属性暴露。
const name = 'xiaoming'; const age = 18; const sayHello = ()=>{ console.log('hello!!!'); } console.log(exports) //{} 空对象 //方法一: module.exports = { name,age,sayHello } //方法二: exports.name = name; exports.age = age; exports.sayHello = sayHello;
Main.js
const Person = require('./Bar') console.log(Person.name); //xiaoming console.log(Person.age); //18 Person.sayHello(); //hello!!!
require(’./Bar’)引入的bar其实是Bar.js中暴露出的对象exports的一个浅拷贝(引用赋值)。
当修改bar中的name值时,Bar.js暴露的exports对象中的name也跟着改变。
在Node中我们经常使用module.exports导出,这两种方式有什么区别呢?
CommentJS中是没有module.pexorts的概念的,但是为了实现模块的导出,Node中使用的是Module的类,每一个模块都是Module的示例,也就是module。
所以在Node中真正用于导出的其实根本不是exports,而是module.exports。因为module才是导出的真正实现者。
为什么exports也可以导出呢?
这是因为module对象的exports属性是exports对象的一个引用。
也就是说 module.exports = exports
Bar.js
const name = 'xiaoming'; const age = 18; const sayHello = ()=>{ console.log('hello!!!'); } const car = '奥迪'; const color = 'red'; const sayRun = () =>{ console.log('红色的奔驰嗖嗖的跑'); } module.exports = { car,color,sayRun } exports.name = name; exports.age = age; exports.sayHello = sayHello;
Main.js
const bar = require('./Bar') console.log(bar); //{ car: '奥迪', color: 'red', sayRun: [Function: sayRun] }
require的值最终取决于module.exports暴露的对象。当设置了module.exports就不带exports玩了。
强调一次:module.exports = exports 。
Bar.js
//module.exports = exports 先执行的 exports = 123
Main.js
const bar = require('./Bar') console.log(bar); //{}
初始状态,exports默认为{}空对象。module.exports = exports
exports = 123时,因为123是值传递所以直接把地址改成值。取消了对{}的引用。但是不影响module.exports的指向。