Node.js是什么
- Node. js 是一个基于 Chrome v8 引擎的服务器端 JavaScript 运行环境
- Node. js 是一个事件驱动、非阻塞式I/O 的模型,轻量而又高效
- Node. js 的包管理器 npm 是全球最大的开源库生态系统
特性
单一线程
Node.js 沿用了 JavaScript 单一线程的执行特性。即在 Node.js 中,JavaScript 的执行线程与其他线程之间同样也是无法共享状态的。
单一线程的最大好处是不用像多线程编程那样处理很容易产生 bug 的同步问题,它从根本上杜绝了死锁问题,也避免了线程上下文交换所带来的性能上的开销。当然了,单一线程的执行方式也有它自身的弱点,譬如,它无法充分发挥多核处理器的性能、一个错误就会导致整个程序崩溃,以及当某一任务执行大量计算时会因长期占用处理器而影响其他异步 I/O 的执行。
事件驱动
在 Web 开发领域,JavaScript 如今在浏览器端正承担了越来越重要的角色,其事件驱动的编程模型也逐渐深入人心。
当然了,这种编程模型虽然具有轻量级、松耦合等优势,但在多个异步任务的场景下,由于程序中的各个事件是彼此独立的,它们之间的协作就成为了一个需要我们费心解决的问题。
异步编程
在 Node.js 中,大部分 I/O 操作都是以异步调用的方式来进行的。Node.js 的开发者们在其底层构建了许多异步 I/O 的 API,包括文件读取、网络请求等。
这样一来,我们就可以很自然地在语言层面上实现并行的 I/O 操作,使得程序中的每个调用都无须等待之前的 I/O 调用结束,从而提高程序的执行效率。
例如,如果我们想要读取两个相互不依赖的文件,如果采用的是异步 I/O,其耗费的时间只取决于读取较慢的那个文件,而如果采用同步 I/O 的话,其耗时就是两个文件的读取时间之和了,异步操作模型带来的优势是显而易见的。
当然了,由于异步编程也会导致代码的编写顺序与其具体执行顺序的不一致,对于很多习惯同步思路编程的人来说,阅读和维护这样的代码会是一个不小的挑战。
常见概念
let、const、var的区别
(1)块级作用域: 块作用域由 { }包括,let和const具有块级作用域,var不存在块级作用域。块级作用域解决了ES5中的两个问题:
内层变量可能覆盖外层变量
用来计数的循环变量泄露为全局变量
(2)变量提升: var存在变量提升,let和const不存在变量提升,即在变量只能在声明之后使用,否在会报错。
(3)给全局添加属性: 浏览器的全局对象是window,Node的全局对象是global。var声明的变量为全局变量,并且会将该变量添加为全局对象的属性,但是let和const不会。
(4)重复声明: var声明变量时,可以重复声明变量,后声明的同名变量会覆盖之前声明的遍历。const和let不允许重复声明变量。
(5)暂时性死区: 在使用let、const命令声明变量之前,该变量都是不可用的。这在语法上,称为暂时性死区。使用var声明的变量不存在暂时性死区。
(6)初始值设置: 在变量声明时,var 和 let 可以不用设置初始值。而const声明变量必须设置初始值。
(7)指针指向: let和const都是ES6新增的用于创建变量的语法。 let创建的变量是可以更改指针指向(可以重新赋值)。但const声明的变量是不允许改变指针的指向。
(8)const对象的属性可以修改吗:
const保证的并不是变量的值不能改动,而是变量指向的那个内存地址不能改动。对于基本类型的数据(数值、字符串、布尔值),其值就保存在变量指向的那个内存地址,因此等同于常量。
但对于引用类型的数据(主要是对象和数组)来说,变量指向数据的内存地址,保存的只是一个指针,const只能保证这个指针是固定不变的,至于它指向的数据结构是不是可变的,就完全不能控制了。