Node 是什么?
:node 使构建在chrome V8 引擎上的一个JavaScript 运行环境
nodejs具备模块系统
导入其他模块,用 require(),这是个全局变量,在任何模块、任何文件都可以使用
node中全局变量不是很多
在node中顶层对象不再是window,压根不存在window,也没有document对象。
而是global(全局的意思)
node.js 跟chrome浏览器非常相似,
相同点:
不管是node 还是 chrome ,使用的语言都是Javascript语言。
所以node的结构跟 chrome 是非常相似的,也都是基于事件驱动的异步架构来实现的
不同点:
浏览器主要是通过事件驱动来服务页面跟用户的交互
node 主要是通过事件驱动来服务 I/O
没有 html、webkit 和 显卡(渲染动画、图像、视频)等等的UI 技术支持,并没有 UI页面
早期构建应用,主要用 CS架构
CS架构? :C 代表客户端,S 代表后台服务 (应用软件)
BS架构? :B 浏览器, S 后台服务(网站)
并行
:在同一个时间点,有多少条指令(代码)正在同时执行
并发
:在某个时间段里,处理了多少个任务
进程
:软件在运行的时候,就一定要CPU处理,就要有对应的硬件去服务
线程
:一个软件不同的功能对应不同的逻辑,每个逻辑就可以抽象为一个线程
软件在运行的时候,进程和线程每样至少有一个
线程主要依附于进程上的,进程不存在也就没有线程了
不同进程 不同线程之间是独立的,所以涉及到数据交互就很麻烦
node.js JavaScript是单进程单线程的,所以可以先不管多线程
单线程弱点:
无法利用多核CPU
都用同一个线程处理,如果有一个地方出错,就会影响全局
I/O密集型
:比如用户访问,要读取数据库,这属于I/O操作,如果用户量特别大,这就是I/O密集型
CPU密集型
:要进行大量的运算
node.js 在I/O密集型中有很大优势,因为它是异步的
模块的导入导出
一个独立的文件就是一个模块
在前端,不能直接读取文件,
要引入js文件,只能通过script标签引入,
通过script引入的js文件,是个独立的文件,但不是一个独立模块
全局环境不止一个,而且全局环境相互之间可以相互共享全局变量的
缺点:当需要的功能、需要的模块、需要的API越来越多的时候,会导致全局环境特别混乱,所以需要模块化的系统
在node中,导入模块:require()
跟script导入有什么区别?
:使用script引入的一整个文件,最大的环境里面的变量默认全局变量,每一个全局变量都会共享,包括顶层对象
而node有了模块系统的时候,就不会这样。
要想导入的模块中的变量由人为决定,怎么实现?
:当前某个模块被引入的时候,被其他模块所依赖的时候,
可以在当前模块决定依赖我们的模块能够拿到什么样的数据,能拿到哪些数据,可以人为的限制,而不是自动的
模块机制的好处?
:可以自己定义导出的对象、属性,换句话来说,每个模块之间的全局变量,不对外公开
是否对外公开,要公开哪几个由自己决定
运行Nodejs
创建一个js文件 --> index.js
再创建一个js文件 --> shownode.js
shownode.js中编写node代码
let a = 1;
index.js 中引入shownode.js模块
const obj = require("./shownode.js") // .js后缀可以省略不写,必须添写/ ./ ../
/*
./ 当前目录
/ 根目录
../ 上层目录
*/
console.log(1);
console.log("obj.a");
运行nodejs代码:
打开终端,进到当前文件夹中 : cd 文件夹名
然后通过node执行文件: node index.js (.js后缀可以省略)
每次修改代码,都要重新执行文件,也就是重复 node index.js这行命令
可看到输出:
为什么输出undefined?
:意思是obj这个对象上没有a这个属性
为什么没有?
node是模块系统,规定每一个文件都是一个模块,
但是模块里面的变量不会成为全局变量,也不会自动导出,也不会默认导出
即使代码改成 console.log(global.a) 结果输出还是不变的
shownode.js模块中的变量 a不是全局变量,这个变量独立于该模块,模块之间的变量无法访问
如何定义一个全局的,在任何模块都能访问到的变量?
挂载到global上(这是定义全局变量的唯一做法)
shownode.js中编写node代码
global.liang = 456;
index.js 中
console.log(global.liang); // 输出 456
一般情况下,在node里面基本不会人为地定义全局变量?
:node具备其他语言所拥有的模块系统,可以规范变量的环境
规范变量环境的好处?
:在前端的时候导入第三方cookie,第三方的库通过命名空间来做的
但命名空间并不是解决不污染的最优的方式,最优的方式就是使用模块系统
通过require 导入一个模块,怎么在被导入模块中定义输出的数据?
: 每个模块文件在node执行的时候,node文件全部编译了一次
拿到文件中所有的字符串,然后放到一个函数function(){} 里面,使其成为了局部变量
require 默认读取模块中的 module.exports属性,对应的值是一个对象,默认是一个空对象
module也是node中的一个全局变量
shownode.js中编写node代码
module.exports = 123456;
index.js中:
const obj = require("./shownode")
console.log(obj); // 输出 123456
shownode.js中编写node代码
module.exports = function() {
console.log("这是模块输出的");
};
index.js中:
const obj = require("./shownode")
obj(); // 输出 这是模块输出的
由上可知,输出什么由module.exports 决定,还可以通过. 来扩展对象属性
shownode.js中编写node代码
module.exports.num = 78910;
index.js中:
const obj = require("./shownode")
console.log(obj.num); // 输出 123456
当需要扩展多个属性时,要重复module.exports,很麻烦,
// 所以用global.exports,它的默认值指向的是module.exports,即global.exports = module.exports(对象引用型)
// 所以不可以对global.exports 进行等号赋值,否则会改变 global.exports 的指向
exports.fn = function () {};