nodeJS学习笔记——node介绍&模块(3)

使用 Node 可以做什么

高性能的网站服务器

实时多人游戏后台服务器

简单易用的命名行应用程序

gulp、less

高大上的桌面应用程序

使用 Web 技术 作为解决方案

底层的物联网开发

移动开发

Ionic 安卓 IOS

使用 Web 技术作为解决方案

CommonJS 规范

nodeJS遵守的规范

一个单独的文件就是一个模块

每一个模块都是一个单独的作用域

每个文件对外接口是 `module.exports` 对象

还有一个别名 `exports` 指向了 `module.exports` 接口对象

`require` 方法用于加载模块,得到模块的 `module.exports` 接口对象

Node 根据 `CommonJS` 规范实现了自己的一套模块系统。

核心模块和文件模块

在 Node 中,模块分为两类,一类是 Node 提供的模块,称为核心模块。另一类是用户编写的模块,称为文件模块。

核心模块在 Node 源代码的编译过程中,编译进了二进制执行文件,

在使用的时候,`require` 参数中直接写核心模块名即可(相当于Java jdk提供的基础类,比如Date,String等,可以直接使用提供的方法)。

例如:`var fs = require(‘fs’)` ,表示加载用于文件操作的 `fs` 核心模块(类似于Java中的引包)。

在Node中,文件模块则是在运行时动态加载,完全以同步的方式加载,然后执行。

浏览器中的模块必须通过网络去加载,所以无论是 SeaJS 还是 RequireJS 都是预先加载所有的模块。

在 Node 中,因为 JavaScript 模块运行在服务器端,加载模块代码的时候可以直接通过本地就可以加载了,

所以,Node 中加载模块都是同步的方式进行加载的,加载到哪里就执行到哪里。

重点: var fs = require(‘fs’)加载模块,相当于Java中的import引依赖

模块加载过程机制

优先从缓存加载

路径分析和文件定位

模块标识符分析

核心模块

路径形式的文件模块

自定义模块

无论是核心模块还是文件模块都是通过 requrie 方法进行加载

1、 优先从缓存中加载(node对于已经加载过的模块会缓存起来,下次如果继续使用,直接从缓存中拿),无论是核心模块还是文件模块

2.1 、如果模块标识是核心模块,那么 node 去读取自己的核心模块

2.2 、如果模块标识是以 . 开头的模块,那么这个模块就是一个相对路径文件模块。

2.3、 既不是路径形式的文件模块,也不是核心模块,是一个包

3.1 、node 先在当前目录下找有没有一个叫做 node_modules 的目录, 如果找到,则找里面有没有对应的包名

3.2、 如果找到该包名对应的目录,找里面的 package.json 文件

3.3 、如果找到 package.json 文件,那么找里面的 main 属性,如果找到 main 属性,直接加载该属性对应的 模块文件

3.4 、如果没有找到 package.json 文件 或者 package.json 文件中没有 main 属性 或者 main 指定的入口文件模块不存在,查找失败

4、 node 自动进入上一级目录 重复上面的步骤

node 中的包模块查找机制非常类似于 JavaScript 中的 作用域链 和 原型链

5、 如果直到 当前文件模块所属的盘符根路径还找不到,最后报错。

总结: 先去缓存中找,缓存没有如果是核心模块就去读自己的核心模块,如果不是按照路径找,路径没有不是文件的话就是包,就去找这个包

文件定位

文件扩展名分析:按照 `.js` `.json` `.node` 的次序补足扩展名

目录分析和包

模块编译

`.js` 文件,通过 fs 模块同步读取文件后编译执行

`.node` 文件

`.json` 文件,通过 fs 模块同步读取文件后使用 `JSON.parse()` 解析返回结果

其它扩展名,被当作 `.js` 文件载入

兼容模块规范

在代码中加入这些判断

if (typeof exports !== ‘undefined’) {

if (typeof module !== ‘undefined’ && module.exports) {

exports = module.exports = _;

}

exports._ = _;

} else {

// 向 Window 暴露接口对象

root._ = _;

}

兼容AMD模块规范

// 判断在全局是否有 define 这个方法,同步 define 有一个属性叫做 amd

// 两个判定条件都成功,就意味着当前浏览器环境引入了 require.js 文件

if (typeof define === ‘function’ && define.amd) {

define(‘underscore’, [], function() {

return _;

});

}

兼容CMD规范

if (typeof define === ‘function’ && define.cmd) {

define(function (require, exports, module) {

module.exports = _;

});

}

node对象

3、Node 中的 JavaScript


REPL (Read Eval Print Loop:交互式解释器) 运行环境 :  可以执行一些js代码

ECMAScript

nodeJS对象

全局对象

global :  相当于浏览器中的window,不建议使用容易造成冲突

Console : 日志打印和浏览器中的console功能相同,(火狐浏览器给JS加的,用于调试,不在规范中)

process : 进程对象, 获取系统相关的信息

Buffer(class): 全局构造函数,用来操作二进制数据

全局函数

setInterval 和 clearInterval

setTimeout 和 clearTimeout

setImmediate 和 clearImmediate

模块内成员

变量:

__dirnam :获取当前文件绝对路径(不包括文件名)

__filename: 获取当前文件的绝对路径(包括文件名)

方法:

require (‘路径’) :  获取模块的方法

exports:

exports= module.exports

exports是引用 module.exports的值,而模块导出的时候,真正导出的执行是 module.exports,而不是exports

module.exports和exports的区别就是var a={}; var b=a; 中a和的区别。exports指向的只是一个引用。改变exports的指向后所添加的exports.***都是无效的。因为require返回的只是module.exports.   所以不能在使用了exports.***之后,改变module.exports的指向。因为exports.***添加的属性和方法并不存在与module.exports所指向的新对象中。

个人建议,可以全部使用module.exports来应对所有的情况,并尽量减少犯错的机会。

module

module对象

Node内部提供一个Module构造函数,所有模块都是Module的实例 • 每个模块内部,都有一个module对象,代表当前模块。

– module.id 带有绝对路径的模块文件名

– module.filename      模块的文件名,带有绝对路径

– module.loaded 表示模块是否已经完成加载

– module.parent 返回一个对象,表示调用该模块的模块。

– module.children      返回一个数组,表示该模块要用到的其 他模块。

– module.exports 模块对外输出的值(暴露模块方法和属性)

module.exports属性表示当前模块对外输出的接口, 其它文件加载该模块,实际上就是读取 module.exports属性 • 点儿导出单个函数、对象或者值的时候非常有用

为了方便,Node为每个模块提供一个exports变量, 指向module.exports。 相当于在每个模块头部,有这样一行命令: var exports = module.exports;

结果就是: – 在对外输出模块接口时,可以向exports对象添加方法

及可以直接使用exports代替module.exports

注意:不能直接给exports赋值,因为这样等于切断了 exports和module.exports的联系

模块加载

require()加载模块

• 在Node.js中,require命令用于加载模块文件

• 基本功能: 1、读取并执行一个JavaScript文件  2、 然后返回该模块的exports对象  3、 如果没有发现指定模块,会报错

require模块加载规则:

• 参数字符串以 “/”开头 (绝对路径)

• 参数字符换以“./”开头 (相对路径)

• 参数字符串没有路径,表示加载核心模块, 或者一个位于各级node_modules目录已安装的模块

• 参数字符串可以省略后缀名 : .js、.json、.node

– .js会当做JavaScript脚本文件解析

– .json会以JSON格式解析

– .node会以编译后的二进制文件解析

注意: node项目目录结构没有要求, 相对路径是相对于node命令所在的目录

核心模块与文件模块

• 核心模块 :require(‘核心模块名’)

• 文件模块 : require(‘路径+模块名’)路径包括相对路径与绝对路径 ,绝对路径的加载速度快

总结

– 加载模块时将运行模块文件中的每一行代码

– 相同模块多次引用不会引起模块内代码多次执行

核心模块:

http : 提供http服务器功能

url :解析url

fs :与文件系统交互

querystring :解析url查询字符串

util :提供一系列实用小工具

path : 处理文件路径

核心模块的源码都在node的lib子目录中。为了提高运行效率,她们安装的时候都会被编译成二进制文件

模块的加载机制:

如果require绝对路径的文件,查找时不会去遍历每一个node_modules目录,其速度最快。 其余流程如下:

1. 从module path数组中取出第一个目录作为查找基准。

2. 直接从目录中查找该文件,如果存在,则结束查找。如果不存在,则进行下一条查找。

3. 尝试添加.js、.json、.node后缀后查找,如果存在文件,则结束查找。如果不存在, 则进行下一条。

4. 尝试将require的参数作为一个包来进行查找,读取目录下的package.json文件,取得 main参数指定的文件。

5. 尝试查找该文件,如果存在,则结束查找。如果不存在,则进行第3条查找。

6. 如果继续失败,则取出module path数组中的下一个目录作为基准查找,循环第1至5个 步骤。

7. 如果继续失败,循环第1至6个步骤,直到module path中的最后一个值。

8. 如果仍然失败,则抛出异常。

总结

所有代码都运行在模块作用域,不会污染全局作用域

模块可以多次加载,但是只会在第一次加载的时候运行 一次,然后运行结果就被缓存了,以后再加载,就直接 读取缓存结果

模块的加载顺序,按照代码的出现的顺序是同步加载的

require是同步加载模块的

路径操作模块:`path`

`path` 是一个核心模块,在使用的时候必须加载。

basename(p[,ext]) 注意第二个参数用法  获取文件名

dirname§  获取文件目录

extname§  获取文件扩展名

isAbsolute(path)  判断是否是绝对路径

join([path1][,path2][,…]) 拼接路径字符串

sep 获取操作系统的文件路径分隔符

文件操作模块:‘fs’

`fs` 是一个核心模块,在使用的时候必须加载。

同步和异步文件系统调用

异步:

总结

面试前要精心做好准备,简历上写的知识点和原理都需要准备好,项目上多想想难点和亮点,这是面试时能和别人不一样的地方。

还有就是表现出自己的谦虚好学,以及对于未来持续进阶的规划,企业招人更偏爱稳定的人。

万事开头难,但是程序员这一条路坚持几年后发展空间还是非常大的,一切重在坚持。

前端面试题汇总

JavaScript

前端资料汇总

  • 20
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值