一、node 基本
1.你了解 Node. js吗?
1. 它是一个Javascript运行环境
2. 依赖于Chrome V8引擎进行代码解释
3. 轻量、可伸缩,适于实时数据交互应用
4. 单进程,单线程 (一个应用程序对应一个进程, 一个进程下面会有多个线程, 每个线程
用于处理任务..)
5. 是一个事件驱动、非阻塞式 I/O 的模型,轻量而又高效;
6. Node. js的包管理器 npm 是全球最大的开源库生态系统。
3、为什么要用 Node. js?
nodejs会让我们的编程工作变得简单,它主要包含如下几点几个好处:
执行快速。
永远不会阻滞。
JavaScript是通用的编程语言。
异步处理机制。
避免并行所带来的问题。
4. nodejs有哪些特点?
是单线程的,但是有很高的可扩展性,使用JavaScript作为主流编程语言。使用的是
异步处理机制和事件驱动。处理高效。
5. Set immediate和set time out 区别
Set immediate就是马上执行的意思。Set time out, 时间参数传为0,
也想获得同样的功能。只不过前者要快一些。
6. 如何更新nodejs的版本?
npm install npm -g
7. 为什么nodejs是单线程的?
Nodejs使用的是单线程没错,但是通过异步处理的方式,可以处理大量的数据吞吐量,
从而有更好的性能和扩可扩展性。
8. 什么是回调函数?
回调函数是指用一个函数作为参数传入另一个函数,这个函数会被在某个时机调用。
9、如何避免回调地狱?
以下方式避免回调地狱
- 模块化:将回调函数转换为独立的函数
- 使用流程控制库,例如[aync]
- 使用Promise
- 使用aync/await
10、Node. js有哪些全局对象?
global、 process, console、 module和 exports。
11.NodeJS 环境中, 模块加载的规范和使用规则是什么?
Nodejs 遵循 Commonjs 规范的模块加载机制,使用 require 加载文件,使用 exports 或module.exports 导出文件
12. module.exports 和 exports 的区别?
1. 区别:
- exports只能使用语法来向外暴露内部变量:如 exports.xxx = xxx;
- module.exports既可以通过语法,也可以直接赋值一个对象。
2. exports和module.exports其实是一个东西,不信我们来输出一下
console.log(module.exports === exports); //输出结果为:true
输出结果是 true 其实就说明它们就是一个东西,其实 exports = module.exports, 因为他们是引用类型的一个变量名,所以当exports再指向一个引用类型的时候, 那么他们就不再全等。
exports = [0, 1];
console.log(exports === module.exports); //输出结果为:false
3. 当然,如果直接通过 exports.xxx 的形式赋值,那么他们依然会指向同一个地址:
exports.array = [0, 1];
console.log(exports === module.exports); //输出结果为:true
这个时候要明白module.exports和exports的区别,就要清楚什么是值类型,什么是引用类型。 我对值类型和引用类型的理解就是,看它是存储在栈上,还是存储在堆上,值类型就是存储在 栈上,引用类型是存储在堆上,但是有个很特殊的情况是,引用类型的名字,是存储在栈上, 然后这个名字指向了堆上的一个地址,从而可以直接使用变量名,调用堆上的数据。
这样可能有点难以理解,我们用代码来简单的认识一下值类型:
let a = 1;
let b = a;
a = 2;
console.log("a的值是:" + a); // 2
console.log("b的值是:" + b); // 1
那么为什么a的值是2,b的值为1呢?是因为当将a赋值给b的时候,相当于是将a的值拷贝给了b也就相当于是重新生成了一个b,那么这个b与a就没有什么关系了,如下图所示:
可以看出,这个时候再去改变变量a的值,那么b的值肯定不会发生变化。 那么引用类型呢:
let a = [1, 2];
let b = a;
a[0] = 0;
console.log("a的值是:" + a); // 0,2
console.log("b的值是:" + b); // 0,2
这个时候为什么输出的结果是0,2呢?这里就涉及到引用类型了,如下图所示:
从图上面看的出来,栈中只是存储了一个变量名字,而数组是存储在堆中。而当将a赋值给b的时候,并不是从堆中拷贝一个数组再让b指向这个数组,而是直接将b指向和a指向的同一个数组。简单来说,可以把变量a看做是银行账户的存折,变量b是银行账户的卡,都是同一个账户,你从存折里面取钱或者存钱,那么卡中的钱也会跟着变多或者变少。
那么我们回到主题,那么我们再来说为什么 module.exports 可以赋值一个对象,而 exports 却不可以。要明白这点,就要从 nodejs 的模块化说起,当 nodejs 执行模块中的代码时,它会将模块中的代码,用一个函数进行包裹:
function (exports, require, module, __filename, __dirname) {}
这里面的其他参数就在这篇文章中不仔细讲解了,不过可以发现,里面有个熟悉的参数module。这里就要说到exports的本质了,正如上面所说exports = module.exports,也就是说他们指向了堆空间的同一个东西,如果对exports进行赋值,那么exports的指向就不一样了,在另外的文件里面就无法再找到通过exports这个变量传递的东西,而module.exports是在执行模块代码中就将module传入到了函数中,所以即使module.exports的值改变也能够在其他文件中进行调用。
再写到这里的时候我产生了一个疑问,如果将 module.exports 的指向改变,那么通过 exports.xxx 传递的值在其他文件中还能进行调用嘛,于是我尝试了下面的代码:
//test.js
exports.add = 100;
module.exports = 1;
//test1.js文件
let test = require("./test");
let p = test.add;
let b = test;
console.log("p的值是:" + p);
console.log("b的值是:" + b);
/*
输出结果是:
p的值是:undefined
b的值是:1
*/
可以看出,改变了module.exports的指向后, exports.xxx 的值在其他文件中也无法调用。
二、npm
1. npm 作用是什么?
允许用户从 NPM 服务器下载别人编写的第三方包到本地使用
允许用户将自己编写的包或命令行程序上传到 NPM 服务器供别人使用
2. 运行 npm run xxx 发生了什么
运行 npm run xxx 的时候,
1. npm 会先在当前目录的 node_modules/.bin 查找要执行的程序,如果找到则运行;
2. 没有找到则从全局的 node_modules/.bin 中查找,npm i -g xxx就是安装到到全局目录;
3. 如果全局目录还是没找到,那么就从 path 环境变量中查找有没有其他同名的可执行程序。
3. 常用的 npm 指令有哪些?
npm init / npm search / npm install / npm remove / npm uninstall
/ npm config set /