打开vscode终端命令:
npm install -g typings
npm install @types/node
function a (){
console.log("我是a中的函数")
}
b.js:
b = 100
a()
text.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<script type='text/javascript' src='./a.js'></script>
<script type='text/javascript' src='b.js'></script>
<script type='text/javascript'>
</script>
</body>
</html>
但是,两个js文件之间不通过html直接运行是不可以直接访问的。
(都没有引入对方怎么可能看得见)
CommonJS规范的提出,主要是为了弥补当前JavaScript没有标准的缺陷。
CommonJS规范对模块的定义十分简单∶
js文件
就是一个模块require()
函数来引入外部的模块。注意: commonJS只是一个规范,没有具体实现。由node进行实现:node根据规范编写相应的js代码。
Node实现了CommomJS规范的规范
默认情况一个js文件(即一个模块)里面的方法或者属性,外面是没法访问的。
如果要让外部可以访问模块里面的方法或者属性,就必须在模块里面通过exports或者module.exports
暴露属性或者方法。
同时在另一个文件中使用require
引入一个方法。
在Node中,每一个js文件中的js代码都是独立运行在一个函数中
,而不是全局作用域,所以一个模块的中使用var
定义的的变量和函数在其他模块中无法访问。
(这里强调的是使用var
,因为在JS中如果不使用var声明的变量就是全局变量,也就不受模块作用域的限制了;
但是声明成全局变量没有意义我们一般不这样用,想要设置成私有变量就用var,想要设置成全局变量就使用export
进行暴露即可)
eg:hello.js:
console.log('hello world')
var x = 100
var y = 200
即hello.js:的代码我们可以看成是这样的:
(function (){
console.log('hello world')
var x = 100
var y = 200
})()
所以无法直接访问另一个文件中访问var变量。
需要将全局可见的变量暴露出去可以通过exports
来进行设置:
只需要将需要暴露给外部的变量或方法设置为exports的属性
即可。
eg:
暴露属性:
exports.x = 100
exports.y = 200
暴露方法:
exports.fn = function (){
console.log('我是一个函数')
}
需要将变量暴露出去也可以通过 module.exports
来进行设置:
module.exports可以通过设置成属性,即.
的形式暴露变量:
module.exports.XXX=XXX
也可以通过module.exports = {}
暴露变量:
module.exports = {
a,
b,
upper
}
require()
可以传递一个文件的路径作为参数,node将会自动根据该路径来引入外部模块
如果使用相对路径,必须以.或..
开头
eg:
require('./hello.js')
require()
引入模块以后,该函数会返回一个对象,这个对象代表的是引入的模块。var md = require('./hello.js')
然后就可以通过 md.变量名
访问另一个文件向外暴露的对象
注意使用如果变量不使用exports声明,是无法将变量引入来的。
hello.js:
console.log('hello world')
exports.x = 100
exports.y = 200
exports.fn = function (){
console.log('我是一个函数')
}
01.js:
var md = require('./hello.js')
console.log(md)
console.log(md.x)
模块分为核心模块和文件模块
var fs = require("fs")
注意: 如果引入的js文件有要执行的内容(如:调用了一个函数),使用require引入该文件的时候,就会执行对应的内容。
在node中有一个全局对象global,它的作用和网页中window类似
在全局中创建的变量都会作为global的属性
保存
在全局中创建的函数都会作为global的方法
保存
eg:
var a = 10
b = 100
console.log(global.a)
console.log(global.b)
输出:
undefined
100
之前我们说一个js文件是运行在一个函数中的,我们来验证一下
console.log(arguments)
输出:
[Arguments] {
'0': { x: 100, y: 200, fn: [Function (anonymous)] },
'1': [Function: require] {
resolve: [Function: resolve] { paths: [Function: paths] },
main: Module {
id: '.',
path: 'c:\\Users\\86198\\VScode\\qianDuan\\Node.js',
exports: [Object],
parent: null,
filename: 'c:\\Users\\86198\\VScode\\qianDuan\\Node.js\\hello.js',
loaded: false,
children: [],
paths: [Array]
},
extensions: [Object: null prototype] {
'.js': [Function (anonymous)],
'.json': [Function (anonymous)],
'.node': [Function (anonymous)]
},
cache: [Object: null prototype] {
'c:\\Users\\86198\\VScode\\qianDuan\\Node.js\\hello.js': [Module]
}
},
'2': Module {
id: '.',
path: 'c:\\Users\\86198\\VScode\\qianDuan\\Node.js',
exports: { x: 100, y: 200, fn: [Function (anonymous)] },
parent: null,
filename: 'c:\\Users\\86198\\VScode\\qianDuan\\Node.js\\hello.js',
loaded: false,
children: [],
paths: [
'c:\\Users\\86198\\VScode\\qianDuan\\Node.js\\node_modules',
'c:\\Users\\86198\\VScode\\qianDuan\\node_modules',
'c:\\Users\\86198\\VScode\\node_modules',
'c:\\Users\\86198\\node_modules',
'c:\\Users\\node_modules',
'c:\\node_modules'
]
},
'3': 'c:\\Users\\86198\\VScode\\qianDuan\\Node.js\\hello.js',
'4': 'c:\\Users\\86198\\VScode\\qianDuan\\Node.js'
}
agruments.callee
属性保存的是当前执行的函数对象,可以进行输出查看验证:
console.log(arguments.callee)
输出:
[Function (anonymous)]
验证:
console.log(arguments.callee+"")
// 拼串会调用toString方法,显示函数结构
输出:
function (exports, require, module, __filename, __dirname) {
console.log(arguments.callee + "")
// 拼串会调用toString方法,显示函数结构
}
结论:在node执行模块的时候,它会将我们写的内容嵌套在如下函数中:
function (exports, require, module, __filename, __dirname) {
自己写的代码内容
}
我们直接使用的exports, require
变量也是通过这个函数传过来的
参数解析:
- exports:该对象用来将变量或函数暴露到外部
- require:函数,用来引入外部的模块
- module:module代表的是当的模块本身,exports就是module的属性
console.log(module.exports == exports)
结果:True
- __filename:表示的是当前模块(js文件)的完整路径
- __dirname:表示的是当前模块所在文件夹的完整路径
eg:
console.log(__filename)
console.log(__dirname)
输出:
c:\Users\86198\VScode\qianDuan\Node.js\01module.js
c:\Users\86198\VScode\qianDuan\Node.js
两者着本质上是一个对象,但是:
.
的方式来向外暴露内部变量exports.XXX=XXX
.
的形式,也可以直接赋值
module.exports.XXX=XXX
module.exports = {}
示例一: 都可以使用.
的方式来向外暴露内部变量
hello.js:
exports.name1 = '孙悟空'
module.exports.name2 = '猪八戒'
01.js:
var hello = require('./hello')
console.log(hello.name1)
console.log(hello.name2)
输出:
孙悟空
猪八戒
示例二: module.exports可以通过直接赋值
暴露对象,而exports不可以
当给module.exports赋值的时候可以访问到:
hello.js
module.exports = {
name2:'猪八戒'
}
01.js:
var hello = require('./hello')
console.log(hello.name2)
输出:
猪八戒
当给exports赋值的时候可以不访问到:
hello.js
exports = {
name2:'猪八戒'
}
01.js
var hello = require('./hello')
console.log(hello.name2)
输出:
undefined
原因其实很简单,变量指向的问题,实际上对外暴露是 module.exports
起的作用,而exports是因为指向它才具有暴露对象的能力。
如果给module.exports
赋值,就是在里面定义向外暴露的对象;
而给exports
赋值,exports就不指向module.exports,就无法定义向外暴露的对象了。