Node.js_1.全局对象、模块

1 Node.js概述

1.1 Node.js概述

1.1.1 Node.js定义

JS是经ECMA统一标准的脚本语言,狭义上的JS指浏览器内置的JS解释器中运行的,主要用途是操作网页内容以实现用户交互;
Node.js由Node.js Foundation维护,基于Google V8引擎的JS运行环境,可以完全脱离浏览器编写独立的服务器端程序。主要用于文件读写、网络访问、加密压缩、数据库操作等
官网:www.nodejs.org/www.nodejs.cn
JavaScript既可以编写客户端应用,也可以编写服务器端应用
JavaScript对象包括ES原生对象、用户自定义对象、宿主对象(浏览器:DOM&BOM对象;Node.js:Node.js扩展对象)

1.1.2 Node.js与JavaScript

比较

1.1.3 安装Node.js

官网:www.nodejs.org
手册网址:nodejs.org/api

1.1.4 运行Node.js

交互模式(REPL模式):命令行直接输入node进入,无需引入Node.js自带的模块;
脚本模式:除了全局对象及其相关成员,其他模块声明的对象和方法必须使用require()引入

1.2 Node.js使用

1.2.1 Node.js体系结构

体系结构

1.2.2 Node.js语法概览

Node.js与JS在数据类型,变量常量,运算符、逻辑结构、函数作用域和闭包、对象和原型、对象分类等内容完全一致。最大的不同点体现在解释器所提供的扩展对象。

1.2.3 数据类型

  1. 原始类型:stirng、number、boolean、null、undefined;
  2. 引用类型:
    ES核心对象->Global、String、Number、Boolean、Date、Array、Error、Function、Object、RegExp
    Node.js对象->Buffer、ReadStream、ClientRequest…
  3. 自定义对象

Node.js不支持任何BOM对象,window、document…也不支持DOM对象,Element、Image、TableRow,…

1.2.4 Node.js的特点

  • 简单,避免过度设计
  • 单线程逻辑处理
  • 非阻塞异步I/O处理
  • 事件驱动编程
  • 无锁机制,不会产生死锁
  • 支持数万个并发连接

适合搭建以IO操作为主、响应速度快、易于扩展的网络应用。如:命令行工具、带GUI界面的本地应用程序、交互式终端程序、单元测试工具、基于社交网络的大规模Web应用、Web Socket服务器、TCP、UDP套接字程序、客户端Javascript编译器;
不适合CPU密集型应用,如:深层次嵌套和递归、复杂加密和解密算法、高可靠性运算、严格内存管理、数据挖掘和数据分析


2 Node.js全局对象

2.1 全局对象

2.1.1 全局对象概述

Global Object,它及其所有属性可以在任何地方访问。
浏览器全局对象window,声明全局作用域的变量和函数默认为window对象的成员——全局对象污染;
Node.js全局对象为global,所有全局变量都是global对象的属性

2.1.2 global

global是全局变量的宿主,在nodejs交互模式下创建的全局变量或函数是global的成员,全局对象污染;而脚本模式下创建的“全局变量和函数”不是global对象的成员,避免全局对象污染。
脚本模式下,每个.js文件都是独立的模块对象,其中创建的“全局变量和函数”是该对象构造方法内的局部成员

2.1.3 console

console模块提供控制台输出机制,用于向标准输出流(stdout)或标准错误流(stderr)输出字符;
常用方法.log()、.info()、.warn()、.error();
利用console.time(‘NAME’)、console.timeEnd(‘NAME’)计算一段代码的总耗时

2.1.4 process

创建进程:操作系统每次启动程序都会分配内存空间将必需的可执行文件和数据文件从文件系统调入内存以执行其中的代码;
全局对象global.process是这个进程的代码表示;
使用process对象获取当前操作系统及运行时的信息,操作脚本所在执行进程。
任务管理器记录系统所有运行的进程;
process对象成员如下:
process.arch,获取CPU架构类型,x64
process.platform,操作系统类型,win32
process.env,环境变量,
process.cwd(),当前工作目录
process.execPath, 解释器所在目录
process.versions, node.js版本信息
process.uptime(), 解释器运行时间
process.memoryUsage(), 内存使用信息
process.pid 获取进程ID号
process.kill() 向指定进程ID号发送终止信号

2.1.5 Buffer

缓冲区,一块专用于存储数据的内存区域,用于存储读写的文件数据、网络上传输的数据等;
Buffer对象实例可以直接构造也可以通过数据读写获得,不仅能存储字符数据,也可以存储二进制字节数据;
Buffer中存储的数据可能很大,所以不会分到到解释器进程的堆栈内存中,而是直接分配在操作系统内存
var buf = Buffer.alloc(5, ‘abj’);//用第二个参数内容填满5个长度的缓冲区
var buf1 = new Buffer(32);//创建长度为32字节的缓冲区
var buf2 = new Buffer([65,64,34]);//创建长度为3字节的缓冲区
var buf3 = new Buffer(‘ABCD’);//创建长度为4字节的缓冲区
buf1.write(“AA”,2);//写入,默认为0
buf1.toString(“utf8”);//指定编码格式的string,用于将buffer存储的数据转为普通字符
不同版本Node.js中Buffer对象的API变化较大,需参考当前版本手册

2.2 全局函数

定时器有四种形式:

  1. 一次性定时器:setTimeout(func, delay),
    一段时间后只执行一次,func代表要执行的任务,是回调函数,可以是箭头函数;delay是间隔的时间,单位毫秒;
    clearTimeout(timerObj):停止一次性定时器对象
  2. 周期性定时器:setInterval(func, delay)
    clearInterval(timerObj):清除周期性定时器;在func内部设置清除定时器的条件,可以让计时器按要求输出
  3. 当前事件循环的结尾立即执行的定时器:process.nextTick(()=>{} ),事件在程序底部执行
  4. 下次事件循环开头立即执行的定时器:setImmediate(()=>{})
    clearImmediate(timerObj),定时器比定时器nextTick()更晚执行
    客户端JS仅支持setTimeout(),setInterval()两组函数

同步和异步:
同步->程序按照顺序执行,先执行前边,后执行后边的。
异步->程序在执行的过程中,遇到异步函数等异步操作,主程序会继续往后,把这些操作放到主程序的最后执行(无论延迟是不是0);

全局函数


3 模块

3.1 模块系统

在这里插入图片描述
Node.js为了优化加载模块的速度,像浏览器一样引入了缓存,加载过的模块会保存到缓存内,从而节省了对相同模块的多次重复加载。
方式:模块加载前会将需要加载的模块名转为完整路径名,该路径名会被保存到缓存中,下次再加载该模块时直接从缓存中取得

查询顺序:先查询缓存,再查询Node自带的核心模块,最后再查询用户自定义的模块

3.1.1 概述

ES6之前,JS没有模块的概念,所有js文件在同一个空间运行,容易产生对象覆盖问题。
Node.js使用"Module"划分功能对象:
1.Node.js中每个.js文件对应一个模块对象,自动含有一个function;
2. 模块声明的变量和函数作用域默认是当前模块,不再是全局作用域;
3. 模块可以导出exports内部的成员,也可以引入require其它模块的成员;
4. Node.js启动时运行的第一个模块称为主模块(main module)

3.1.2 模块分类

  1. 核心模块
  2. 第三方模块
    基于Node.js核心模块,http://www.npmjs.com/ ,常用第三方模块:express、less、webpack…
  3. 自定义模块
    文件式自定义模块
    目录式自定义模块

3.1.3 核心模块

global:全局对象模块;
console:控制台模块;
util:常用函数的集合,用于弥补核心JS的功能过于简单;
events:实现Node.js的事件驱动型的异步调用;
fs:文件系统I/O操作模块
http:提供基于HTTP协议的请求和响应
net:提供基于Socket的网络连接
dns:DNS解析服务模块
crtpto:加密和解密功能模块

Eg. 对字符串url转化成对象
1.核心模块名称直接引入
var qs = require(‘querystring’);
2.使用qs的方法解析字符串
var obj = qs.parse(str);

3.1.4 加载模块

引入模块,需要经历三个步骤:路径分析、文件定位、编译执行;核心模块在node源代码编译过程中被编译成二进制执行文件,当进程启动时,核心模块被直接加载进内存,所以核心模块被引入时可以省略文件定位和编译执行这两个步骤,并且在路径分析中优先判断,所以加载速度最快。

//引入http模块,调用
var http = require(‘http’);
var serv = http.createServer(…);
serv.listen(3000);

//引入querystring模块
var qs = require(‘querystring’);
console.log(qs.parse(str));//解析一个HTTP请求消息中的查询字符串

3.2 自定义模块

3.2.1 创建模块

文件式自定义模块:
exports:引用module.exports,用于导出当前模块成员供其他模块使用;

Node.js在编译模块文件时会对其首尾进行包装:

(function(exports,require,module,__filename,__dirname){
  //__filename 文件的完整路径和名称
  //__dirname 文件的完整路径
  // require  用于引入其它的模块 **./file_name表示同一目录下文件**
  //引入其它模块exports的对象后var obj=require('...'); ,只需要obj.fn1调用对象内的函数

  //exports/module.exports 导出当前模块,是一个对象{}; 
  //module.exports本质上是一个对象, **如果需要导出多个方法**,只需要module.exports.fn1=fn1;module.export.fn2=fn2;

  module.exports = {};
  exports = module.exports;
  程序员自己编码的代码 
  return module.exports;
})

3.2.2 加载模块

文件模块在运行时动态加载,需要完整的路径分析、文件定位和编译执行过程,加载速度比核心模块慢
require()函数用于加载第三方模块,可用参数如下:
原生模块名:http、fs、url等;
文件模块的相对路径:…/mod1等;
文件模块的绝对路径:/…/…/mod2
非原生模块的文件模块名:mod3
第一次require()某个模块,Node.js会查找并加载对应的文件,创建对应的模块对象,保存在缓存中,并返回该对象;后续再次require()同一个模块,首先在缓存中查找,直接返回该对象
从其他js文件调用,使用require包含一个相对工作目录的js文件
//调用自定义模块:注意路径,js文件和目标文件的相对路径
var p = require(’./person’);
console.log(p.name);
p.work();
require加载模块时,如果省略文件类型,Node.js会首先认为是.js文件,然后是.json文件,最后是.node文件,都没有找到的话抛出异常。
由于Node.js是单线程执行,且Node.js加载模块时线程阻塞,所以为了加快require模块的加载,只要不是.js文件在require的时候都要把文件类型加上

3.2.3 覆盖exports

重写module.exports,实现对象的封装;require调用时会得到一个对象;

//构造对象
function Person(name, age) {
  this.name = name;
  this.age = age;
  this.intro = function() {
  console.log(`i am ${ this.name }.);
};}
module.exports = Person;

3.2.4 目录式自定义模块(文件夹)

模块与文件一一对应:
单个文件:js代码文件或者二进制代码文件;
文件夹:文件夹封装为模块,即package;
目录式自定义模块需要创建一个index.js文件作为入口文件;
//为index.js文件添加代码,在文件夹外的js文件中调用
//定义模块中的功能
exports.hello = function() {};
//调用目录中的模块
var p = require(’./index.js所在文件夹’);
p.hello();

如果使用require(’./文件夹名称’),会自动寻找当前文件夹下的index.js文件;

猜你喜欢

转载自blog.csdn.net/qq_33392141/article/details/83998528