全局对象API预览
全局:路径变量
- __filename:展示当前的文件名称,从主目录开始的绝对路径
- __dirname:展示当前文件所在的文件目录的名称,从主目录开始的绝对路径
任务要求:
- 在控制台输出
__filename
和__dirname
两个变量 - 完成项目目录下,’views’ 子目录中,网页模板 ‘view.html’ 的路径拼接
- 在控制台输出拼接后的路径信息
#!/usr/bin/node
console.log("filename:",__filename);
console.log("dirname:",__dirname);
/*在文件操作的时候,可以进行目录的拼接,可以用一个文件的绝对路径和相对路径从而得到一个文件
的绝对路径*/
/*method1*/
var file = __dirname + "/view/base.html";// 这种方法并没有考虑不同的操作系统
/*method2*/
var file;
switch(process.platform){
case "Linux":
file = __dirname + "/view/base.html";
break;
case "win32":
file = __dirname + "\\view\\base.html";
break;
default:
file = "error";
}
/*method3*/
const path = require("path");
file = path.join(__dirname,"view","base.html");
## 输出结果
filename: /home/wangding/node.js/nodejs-demo/02-global-var/01-file-dir-name.js
dirname: /home/wangding/node.js/nodejs-demo/02-global-var
全局:控制台
控制台输出信息
console控制台:console
用于提供控制台标准输出,它是一种调试工具,后来逐渐成为了标准
方法 | 描述 |
---|---|
console.log() |
向标准输出流打印字符并以换行符结束 |
console.info() |
向标准输出流打印信息性消息。输出文字外,会显示一个蓝色的惊叹号。 |
console.warn() |
向标准输出流打印警告性消息。输出文字外,会显示一个黄色的惊叹号。 |
console.error() |
向标准输出流打印错误性消息。输出文字外,会显示一个红色的叉子。 |
任务要求:
-
定义一个 user 对象,包含三个字段:name, age, qq
-
使用三种占位符,分别输出三种变量类型:字符串,整数和 JSON 数据
-
以两种不同占位符的方式输出
user.qq
信息 -
向标准错误流中输出信息:
Error:something wrong!
-
通过命令行重定向,观察 console.log 和 console.error 两个方法所使用流的区别
./01-format.js > output.txt ./01-format.js 2> error-msg.txt
#!/usr/bin/node
const user = {
name:"frewen",
age:21,
qq:"2622860598"
};
const log = console.log;
//method1
log("name: %s",user.name); // string类型
log("age: %d",user.age); // number类型
log("user: %j",user);// json字符串
//method2
log("qq: " + user.qq);// 字符串拼接 通过+进行连接
//method3
log(`qq: ${user.qq}`);
console.error('Error:something wrong!');
# 输出重定向
在输出控制台中console.log()和console.error()没有什么区别,所以可以通过Linux的输出重定向
控制台基准测试
- 对耗时任务运行的时间进行采样
- 在控制台输出采样的时间
- 多运行几次程序,观察同样的耗时任务每次采样的时间是否相同(结果是不同的)
#!/usr/bin/node
function longTask(){
var n = 0;
for(var i = 0;i<1000;i++){
for(var j = 0;j<1000;j++){
n = n + i*j;
}
}
}
console.time("test");// 确定任务开始
longTask();
console.timeEnd("test");// 确定任务结束 两个console的参数必须是一样的
## 输出结果
test:91.867ms // 每次测试的结果是不同的
全局:进程
获取平台信息
- 向控制台打印 CPU 架构信息以及操作系统版本信息
- 打印进程 id 信息以及 Node.js 可执行文件的绝对路径信息
- 在脚本中增加标准输入流的读取操作,让程序暂停执行
- 执行 Linux 命令
ps aux
,验证当前进程的 ID 信息和程序中得到的进程 ID 信息相同 - 打印 Node.js 版本信息,当前登录用户 id 信息,当前登录用户所属组 id 信息以及当前脚本所在路径信息
- 在命令行执行 ‘node -v’ 命令,验证程序输出的 node.js 版本信息是否正确
- 在命令行执行 ‘id’ 命令,验证程序输出的登录账户 id 信息是否正确
- 在命令行执行 ‘pwd’ 命令,验证程序输出的当前工作目录信息是否正确
- 打印内存使用情况
- 打印环境变量
- 在命令行执行 ‘env’ 命令,验证程序输出的环境变量信息正确
#!/usr/bin/node
const log = console.log;
/*向控制台打印 CPU 架构信息以及操作系统版本信息*/
log("arch: ",process.arch);
log("platform: ",process.platform);
## 输出结果
arch: x64
platform: linux
/*打印进程 id 信息以及 Node.js 可执行文件的绝对路径信息*/
log("id: ",process.pid);
log("execPath: ",process.execPath);
## 输出结果
id: 2569
execPath: /usr/bin/node
/*在脚本中让程序暂停执行*/
process.stdin.pause();
/*打印 Node.js 版本信息,当前登录用户 id 信息,当前登录用户所属组 id 信息以及当前脚本
所在路径信息*/
log("version: ",process.version);
log("uid: ",process.getuid());
log("gid: ",process.getgid());
log("pwd: ",process.cwd());
## 输出结果
version: v6.10.1
uid: 1000
gid: 1000
pwd: /home/wangding/node.js/nodejs-demo/04-process
/*打印内存使用情况*/
log("rss: ",process.memoryUsage().rss);// 查看系统的常驻内存大小
log("heapTotal: ",process.memoryUsage().heapTotal);//查看 V8 动态分配的总内存大小
log("heapUsed: ",process.memoryUsage().heapUsed);//查看 v8 动态分配的已用内存大小
log("external: ",process.memoryUsage().external);
//查看 v8 管理的绑定到 JS 对象上的 C++ 对象的内存
## 输出结果
rss: 14946304
heapTotal: 7376896
heapUsed: 3498472
external: 8380
/*打印环境变量*/
log("env: ",process.env);
获取命令行参数
- 获取命令行参数,命令行参数为一个数学表达式
- 如果没有命令行参数,打印程序的使用说明
- 如果命令行参数是 –help 或者 -h,打印程序的使用说明
- 如果命令行参数多于 3 个,多余的参数忽略
- 对命令行参数的表达式进行求值,打印求值结果
- 命令行参数的格式如下:
#!/usr/bin/node
// argv 是一个字符串数组 头两个字符串 第一个字符串是node 第二个参数是运行的脚本的绝对路径
/*
console.log(process.argv.length);
for(var i = 0;i<process.argv.length;i++){
console.log(`${i}:argv - ${process.argv[i]}`);
}
*/
if(process.argv.length === 2 || process.argv[2] == "--help" || process.argv[2] == "-h"){
console.log("usage: cmd-name [OPTION] [expression]\nevaluate the expression.\n\nMandatory arguments to long options are mandatory for short options too.\n-h, --help output help information and exit"
)} else{
console.log(process.argv[2] + "=" + eval(process.argv[2]));
}
# 输出格式
./02-calc.js
usage: cmd-name [OPTION] [expression]
evaluate the expression.
Mandatory arguments to long options are mandatory for short options too.
-h, --help output help information and exit
./02-calc.js 2+4
2+4=6
./02-calc.js 2\*Math.PI
2*Math.PI=6.283185307179586
处理退出码
退出码实质上是给程序看的,在Linux程序中,有时候子进程会输出退出码,父进程通过查看子进程输出的退出码来判断是否正确
- 通过命令行参数获取程序的退出码,以该退出码退出程序
- 通过 echo 命令查看程序的退出码
- 对命令行参数的退出码,做数据合法性校验
#!/usr/bin/node
var code = process.argv[2];
if(typeof code === 'number'){
console.log("命令行参数类型不符合!");
process.exit(1);
}
if(process.argv.length <3){
console.error("请给出命令行参数!");
process.exit(1);
}
process.exit(code);
// process.exit(code:number) ?表示可以有也可以表示没有
// 获取退出码 echo $?
操作标准输入输出流
- 逐条打印提示信息:姓名、邮箱、QQ、手机
- 读取用户键盘输入信息,保存到对象中
- 用户键盘输入结束后,打印完整的对象信息
#!/usr/bin/node
const msg = ['name','email','qq','mobile'];
var i = 0,
me = {};
console.log(msg[i] + ':');
process.stdin.on('data',(data)=>{
me[msg[i]] = data.slice(0,data.length-1).toString('utf-8');// slice 是将回车进行去掉
i++;
if(i == msg.length){
console.log(me);
process.exit();
}
console.log(msg[i] + ':');
});
process.stdin.on('end',()=>{
console.log(me);
});
处理信号量
- 接收信号量,并对信号(SIGINT 和 SIGTSTP)进行处理
- 用控制台快捷键,给程序脚本发送信号量,测试程序的功能逻辑
- CTRL+C 发送 SIGINT 信号量,让程序退出
- CTRL+Z 发送 SIGTSTP 信号量,让程序挂起
- 用 kill 命令,给程序脚本发送信号量,测试程序的功能逻辑
#!/usr/bin/node
process.stdin.resume();
process.on('SIGINT',()=>{
console.log('you have pressed Ctrl+C');
process.exit();
})
process.on('SIGTSTP',()=>{
console.log('you have pressed Ctrl+Z');
})
// 杀掉程序的两种方式
/*
第一种: 通过 Ctrl+C 和 Ctrl+Z
第二种: 通过kill -2 pid 和 kill -20 pid
*/
实现 my-kill 程序
- 获取命令行参数,得到进程 ID 信息和信号量标识符
- 向指定进程 ID 的进程发送特定的信号量
- 用 05-my-kill.js 脚本,向 05-signal.js 脚本发送信号量,测试两个程序的功能逻辑
#!/usr/bin/node
const pid = process.argv[2];
const sig = process.argv[3];
process.kill(pid,sig);
全局:定时器
实现延迟执行任务
- 定义一个定时炸弹对象
- 定时炸弹对象和 setTimeout 函数绑定
- 定时炸弹爆炸
- 在定时炸弹爆炸之前,拆除定时炸弹
#!/usr/bin/node
/*console.log('first');
global.setTimeout(function(){
console.log('second');
},2000);
//说明JavaScript的异步执行
console.log('third');*/
function Bomb(){
this.message = 'Bomb';
}
Bomb.prototype.explode = function(){
console.log(this.message);
}
var b = new Bomb();
// 此时直接执行时,this指向的是timeout对象
var time = global.setTimeout(b.explode.bind(b),2000);
//global.clearTimeout(time);
实现定时执行任务
- 定时执行任务
- 用两种方式取消定时器,分别是:
- 设置定时器运行时间总时长,时间到后取消定时器;
- 设置计数器,重复执行任务次数达到上限,取消定时器;
#!/usr/bin/node
console.log("start");
const time = global.setInterval(loop,500);
function loop(){
// count ++;
console.log('I will loop forever');
if(count === 6){
clearInterval(time);
}
}
// method1
global.setTimeout(function(){
global.clearInterval(time);
console.log('end');
},3000);
// method2
var count = 0;
Node.js Buffer(缓冲区)
JavaScript 语言自身只有字符串数据类型,没有二进制数据类型。
但在处理像TCP流或文件流时,必须使用到二进制数据。因此在 Node.js中,定义了一个 Buffer 类,该类用来创建一个专门存放二进制数据的缓存区。
在 Node.js 中,Buffer 类是随 Node 内核一起发布的核心库。Buffer 库为 Node.js 带来了一种存储原始数据的方法,可以让 Node.js 处理二进制数据,每当需要在 Node.js 中处理I/O操作中移动的数据时,就有可能使用 Buffer 库。原始数据存储在 Buffer 类的实例中。一个 Buffer 类似于一个整数数组,但它对应于 V8 堆内存之外的一块原始内存。
Buffer基本操作
- 实例化一个 buffer 对象 buf1,缓冲区的大小是 256 字节,初始化第一个字节为23,控制台打印 buf1 的长度和内容
- 通过循环初始化 buf1 的每个字节,每个字节比上个字节大 1,控制台打印 buf1 的内容
- 对 buf1 做切片操作,取出后 10 个字节,存放到 buf2 中,控制台打印 buf2 的内容和长度
- 对 buf2 做填充操作,所有字节填充为零,控制台打印 buf2 的内容
- 用数组(数组内容随意)初始化 buf3,控制台打印 buf3 中的内容和长度
- 用字符串(字符串内容随意)初始化 buf4,控制台打印 buf4 中的内容和长度,打印 buf4 字符串
- 将 buf4 的内容复制到 buf3 中,打印复制后的 buf3 内容和长度,打印 buf3 字符串
#!/usr/bin/node
// 初始化对象 new Buffer()
const log = console.log;
var buf1 = new Buffer(256);
buf1[0] = 23;
log('buf1 length:',buf1.length);
log('buf2 content:',buf1);
// 循环初始化
for(var i = 0;i<buf1.length;i++) buf1[i] = i;
log('buf1 new content:',buf1);
// 切片填充操作
var buf2 = buf1.slice(246,257);
log('buf2 length:',buf2.length);
log('buf2 new content:',buf2);
buf2.fill(0);
log('buf2 fill content:',buf2);
// 数组进行初始化
var arr = ['a',0xBA,0xDF,0x00,0x00,255,10];
var buf3 = new Buffer(arr,'utf-8');
log('buf3 length:',buf3.length);
log('buf3 content:',buf3);
// 字符串初始化
var buf4 = new Buffer('Hello World','utf-8');
log('buf4 length:',buf4.length);
log('buf4 content:',buf4);
log('buf4 string content:',buf4.toString('utf-8'));
// 复制内容
buf3.copy(buf4);
log('buf3 length:',buf3.length);
log('buf3 content:',buf3);
/*
buf.copy(targetBuffer[, targetStart[, sourceStart[, sourceEnd]]])
参数描述如下:
targetBuffer - 要拷贝的 Buffer 对象。
targetStart - 数字, 可选, 默认: 0
sourceStart - 数字, 可选, 默认: 0
sourceEnd - 数字, 可选, 默认: buffer.length
*/
Buffer 编码
在计算机中,文件的编码有两种方式,一种方式是通过文本文件进行编码(例如:utf-8 ascii utf16le
),另一种方式是通过二进制文件进行编码的(例如:base64 lantin1 hex
)
其中对于base64
编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。采用Base64编码具有不可读性,需要解码后才能阅读。
HTTP对于用户名和密码的校验主要通过两种方式
- 基本校验:用户名和密码之间通过冒号
:
进行分隔,之后通过base64
编码形成加密文件,上传至服务器,服务器通过解密进行解密 - 摘要校验:通过MD5码进行校验
任务要求:
- 从命令行参数获取登录网站的用户名和密码信息
- 命令行参数的格式:
cmd user_name password
- 命令行参数不正确时,提示用户命令行参数的正确格式
- 在控制台打印用户名和密码信息
- 将用户名和密码信息拼接成一个字符串,用冒号(:)分割
- 将拼接后的字符串转化成 base64 编码,并打印在控制台上
#!/usr/bin/node
if(process.argv.length !== 4){
console.log('请输入正确的参数个数');
process.exit(-1);
}
const name = process.argv[2],
pwd = process.argv[3];
if(name == '' || pwd == ''){
console.log('请输入正确的参数!');
process.exit(-1);
}
var str = name + ':' + pwd;
var buf = new Buffer(str);
console.log("base64 content:",buf.toString('base64'));
Buffer 解码
- 从命令行参数获取用户名和密码信息的 base64 编码字符串
- 命令行参数的格式:
cmd base64_string
- 命令行参数不正确时,提示用户命令行参数的正确格式
- 将 base64 编码的字符串转换成 utf8 编码的字符串
- 将还原后的用户名和密码信息打印在控制台上
- 还原信息不正确时,请提示错误信息
#!/usr/bin/node
if(process.argv.length !== 3 || process.argv[2] == ''){
console.log('请按照命令行参数的格式:cmd base64_string输入合法的参数');
process.exit(-1);
}
const str = process.argv[2];
var buf = new Buffer(str,'base64');// 后面的编码格式不能缺少
var namepwd = buf.toString('utf-8');
var data = namepwd.split(':');
if(data.length !== 2){
console.error('信息有误!');
process.exit(-1);
}
console.log("name:" + data[0] + ' pwd:' + data[1]);
Buffer 实现 Data URI
DATA-URI 是指可以在Web 页面中包含图片但无需任何额外的HTTP 请求的一类URI.(类似将图片的base64码添加到src
属性上)
- 从命令行参数获取图片文件名
- 命令行参数的格式:
cmd file_name
- 命令行参数不正确时,提示用户命令行参数的正确格式
- 命令行参数的图片文件不存在时,提示错误信息
- 把图片数据生成 data URI 格式的数据
- 把 data URI 数据打印到控制台
- 把 data URI 数据嵌入到 HTML 页面中
- 创建一个 HTTP 服务,监听 8080 端口
- 浏览器请求 HTTP 服务的 URL 地址时,得到嵌入图片数据的 HTML 页面
任务提示:
> 文件操作需要导入 fs 模块: const fs = require('fs');
> 读取文件数据可以使用 readFileSync 方法:var data = fs.readFileSync(fileName);
> 同步读取文件时,如果文件不存在会抛出异常,可以使用 try-catch 捕获异常
> 获取文件扩展名,需要导入 path 模块:const path = require('path');
> 获取文件扩展名使用 path 模块的 extName 方法:var ext = path.extname(fileName);
const http = require('http'),
fs = require('fs'),
path = require('path');
var filename = process.argv[2];
if(process.argv.length !== 3) {
console.error('命令行参数格式:cmd fileName');
process.exit(-1);
}
try {
var data = fs.readFileSync(filename).toString('base64');
} catch(e) {
console.error(e.message);
process.exit(-1);
}
var ext = path.extname(filename);
var datauri = 'data:img/' + ext.slice(1,ext.length) + ';base64,' + data;
html = '<!DOCTYPE html><html><head><title>img</title></head><body><img src="' + datauri + '"/></body></html>';
http.createServer((req,res)=>{
res.end(html);
}).listen(8080);
Buffer 读取位图信息
读取一个BMP文件,需要知道二进制文件的存储的三方面内容:
- 位置:也就是对应的偏移量(相较于第一个位置的偏移量)
offset
- 大小:4byte 8byte
- 含义:这一个字段代表是什么含义
下列显示的所对应的offset以及size:
任务要求:
- 从命令行参数获取图片文件名
- 命令行参数的格式:
cmd file_name
- 命令行参数不正确时,提示用户命令行参数的正确格式
(length)
- 命令行参数的图片文件不存在时,提示错误信息
(try catch)
- 获取图片的宽度、高度和颜色深度三个信息,并打印在控制台上
#!/usr/bin/node
const filename = process.argv[2],
fs = require('fs'),
buf = fs.readFileSync(filename),
log = console.log;
log('BMP width:',buf.readUInt32LE(18));
log('BMP Height:',buf.readUInt32LE(22));
log('color deapth:',buf.readUInt16LE(28));
/*
buf.readUInt32LE(offset[, noAssert])
根据指定的偏移量,使用指定的 endian 字节序格式读取一个无符号 32 位整数,小端对齐。 若参数 noAssert 为 true 将不会验证 offset 偏移量参数。 这意味着 offset 可能会超出buffer 的末尾。默认是 false。
*/
Buffer 写入位图文件
- 从命令行参数获取图片文件名
- 命令行参数的格式:
cmd file_name
- 命令行参数不正确时,提示用户命令行参数的正确格式
- 写一个 16 * 16 像素,颜色深度为 32 位的位图文件
- 位图的所有像素为红色
#!/usr/bin/node
const fs = require('fs');
const width = 16,
height = 16;
var pixelByteSize = width * height * 4;
var totalSize = pixelByteSize + 54;
var buf = new Buffer(totalSize);
buf.fill(0);
// head
buf.write('BM');
buf.writeUInt32LE(totalSize, 0x02);
buf.writeUInt32LE(54, 0x0a);
buf.writeUInt32LE(40, 0x0e);
buf.writeUInt16LE(1, 0x1a);
buf.writeUInt16LE(32, 0x1c);
buf.writeUInt32LE(pixelByteSize, 0x22);
buf.writeInt32LE(width, 0x12);
buf.writeInt32LE(height, 0x16);
// data
for(var i=54; i<totalSize; i+=4) {
buf.writeUInt32LE(0xff0000ff, i);
}
fs.writeFile('./out.bmp', buf, (err) => {
if(err != null) {
console.error(err);
process.exit(1);
}
});
全局:模块管理
Node应用是由模块组成的,Node遵循了CommonJS的模块规范,来隔离每个模块的作用域,使每个模块在它自身的命名空间中执行。
JS 模块化的两种方案分别是:AMD
和 CommonJS
-
AMD
规范的主要内容:AMD
是异步模块加载机制。从它的规范描述页面看,AMD很短也很简单,但它却完整描述了模块的定义,依赖关系,引用关系以及加载机制。define和require这两个定义模块、调用模块的方法,合称为AMD模式 -
CommonJS
规范的主要内容:模块必须通过 module.exports 导出对外的变量或接口,通过 require() 来导入其他模块的输出到当前模块作用域中。
使用第三方模块
- 导入 date-now 模块
- 调用 date-now 模块的 now 方法,在控制台打印 now 的运行结果
- 安装 date-now 模块,运行程序
- 创建 package.json 文件,用 npm install module-name -S 安装模块
- 查看 package.json 文件中的依赖项
#!/usr/bin/node
var now = require('date-now');
console.log(now());
console.log(Date.now());
## 输出结果
1537882086300
1537882086304
在程序运行的时候,程序会报错,因为对于该程序,没有date-now这个模块,因此,需要先通过npm包管理器进行安装
#npm缩写于 Node Packaged Modules, 是 node.js 的模块管理器
~/node.js/nodejs-demo/07-module(master) » npm install date-now
关于在每一个包管理器中的package.json文件,这个文件是一个项目配置文件,里面有项目配置的一些信息,同时该文件还包括所需要的模块依赖项
使用 package.json
配置文件管理第三方模块的过程:
- 首先我们创建一个文件夹package,在这个文件夹里面初识一个
package.json
文件
~/package » npm init
# 此时我们打开package.json文件
~/package » cat package.json wangding@OFFICE
{
"name": "package",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"date-now": "^1.0.1"
}
}
其中需要注意"devDependencies"
和"dependencies"
,其中前者是开发时以来的npm模块,后者是自己所写的打包成的应用程序所需要的npm模块
- 安装第三方模块:
npm install moduleName -S(--save)
,此时该模块会自动添加到package.json
文件里的"dependencies"
里面 - 发布程序和 package.json 配置文件(发布到npm网站上),然后使用时:运行 npm install 安装第三方模块就可以使用自己的创建的第三方模块了
如果我们使用的是别人的npm的包管理器的时候,只需要在别人的项目下运行npm install命令,就可以让程序自动下载程序运行时所需要的所有模块
创建并使用模块,导出变量
- 在 02-export-var.js 脚本中导出变量 Math.PI打印 module 信息
- 在 02-main.js 脚本中导入上面的模块
- 测试模块的接口,观察 module 中的 exports 信息
#!/usr/bin/node
// export-var.js
module.exports = Math.PI;
console.dir(module);// dir是输出一个对象
#!/usr/bin/node
var PI = require('./02-export-var');
console.log('\n'+ PI);
console.log();
console.dir(module);
创建并使用模块,导出函数
- 在 02-export-function.js 脚本中定义 circle 函数
- 函数的入口参数是圆的半径
- circle 函数返回一个对象
- 对象中有两个成员函数,分别计算:圆的面积和周长
- 导出 circle 函数
- 在 02-main.js 脚本中导入上面的模块
- 测试模块的接口,观察 module 中的 exports 信息
#!/usr/bin/node
// 02-export-function.js
function circle(radius){
return {
diameter:function(){return 2*radius;},
circumference:function(){return 2*Math.PI*radius;},
area:function(){return Math.PI*radius*radius;}
};
}
module.exports = circle;
var circle = require('./02-export-function');
const log = console.log;
log(circle(20).diameter());
log(circle(20).circumference());
log(circle(20).area());
创建并使用模块,导出对象
- 在 02-export-object.js 脚本中定义 Circle 对象字面量
- Circle 对象有三个公开方法,分别计算圆的直径、面积和周长
- 导出 Circle 对象,打印 module 信息
- 在 02-main.js 脚本中导入上面的模块
- 测试模块的接口,观察 module 中的 exports 信息
#!/usr/bin/node
// 02-export-object.js
module.exports = {
diameter: function(radius){return 2*radius;},
circumference:function(radius){return 2*Math.PI*radius;},
area:function(radius){return Math.PI*radius*radius;}
}
var circle = require('./02-export-object');
const log = console.log;
log(circle.diameter(20));
log(circle.circumference(20));
log(circle.area(20));
使用全局对象 global
- 在 03-global.js 定义模块级变量 pi, 函数 circle 以及对象字面量 objCircle
- 编写 03-main.js 脚本,导入 03-global.js 脚本
- 使用 03-global.js 脚本中的变量、函数和对象
- 运行 03-main.js,观察程序结果,理解程序出错的原因
- 修改 03-global.js 脚本,将变量、函数和对象定义为全局的
- 运行 03-main.js 脚本,观察程序结果,理解程序工作原因
#!/usr/bin/node
// 03-global.js
global.pi = Math.PI;
global.circle = (radius)=>{
return {
circumference:function(){return 2*Math.PI*radius;},
area:function(){return Math.PI*radius*radius;}
}
}
global.circleobj = {
circumference:function(radius){return 2*Math.PI.radius},
area:function(radius){return Math.PI*radius*radius}
}
#!/usr/bin/node
// 03-main.js
require('./03-global.js');
console.log(global.pi);
console.log(global.circle(20).circumference());
console.log(global.circleobj.area(20));
使用模块级变量在对象间共享信息
- 编写 04-share.js 脚本,定义模块级变量 count,定义构造函数 Num
- Num 有两个公开方法:add 让 count 加一,getCount 得到 count 的值
- 导出构造函数 Num
- 编写 04-main.js 脚本,导入 Num 构造函数
- 用 Num 实例化 n1 和 n2 两个对象
- n1.add() 方法调用两次,控制台打印 n1.getCount() 和 n2.getCount()
- n2.add() 方法调用一次,控制台打印 n1.getCount() 和 n2.getCount()
- 运行 04-main.js 程序,观察程序运行结果,理解程序工作原理
#!/usr/bin/node
// 04-share.js
var count = 0;
function Num(){
this.add = ()=>{count++;}
this.getcount = ()=>{console.log(count);};
}
module.exports = Num;
#!/usr/bin/node
// 04-main.js
var Num = require('./04-share.js');
var n1 = new Num();
var n2 = new Num();
n1.add();
n1.add();
n1.getcount();
n2.getcount();
n2.add();
n1.getcount();
n2.getcount();
## 输出结果
2
2
3
3
npm模块的目录结构和程序结构