nodeJS学习笔记——node介绍&模块(3),互联网公司面试真题

路径形式的文件模块

自定义模块

无论是核心模块还是文件模块都是通过 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. 如果仍然失败,则抛出异常。

总结

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

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

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:前端)
img

前!**
因此收集整理了一份《2024年Web前端开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-HqY7Hghe-1710887745077)]
[外链图片转存中…(img-FU0CO8MV-1710887745078)]
[外链图片转存中…(img-mCpZacoX-1710887745079)]
[外链图片转存中…(img-cNJqiift-1710887745079)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:前端)
[外链图片转存中…(img-9NIRs1OT-1710887745080)]

  • 20
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值