提前声明:本文皆以自己为视角来记录自己学习node的过程,故不当做教程发布。刚开始初学不乏有认知错误的地方,请读者斟酌,如有误还望评论区内指出,鄙人定不耻下问虚心求救,一起提升。
每种语言都有自己的运行环境,什么是运行环境?javaScript这门语言为什么可以在浏览器中运行?换句话说,为什么浏览器可以识别javascript这门语言的代码?为什么我就不能用java,C++,这种语言来开发网页呢?这样解释的话,浏览器就是javaScript的运行环境。
具体为什么会出现Node这个东西,那就要说起服务器和数据库I/O性能的问题了,因为服务器和数据库的I/0输入输出模式,导致了这部分为了解决高并发问题优化起来非常困难,那么怎么提升web性能呢?只能从传统的客户端到服务器这一头传统的java ,c语言写出的服务器脚本都是多线程,客户端每向服务器发送一个请求,就会分配一个线程来为这个请求服务,而服务器到数据库请求的过程中,这个服务器线程是没事干的。
就好比一去餐厅吃饭,餐厅为每一个桌都分配一个服务员,而服务员和你沟通的时间就仅仅只有点菜的时间,她把菜单给厨师,厨师在炒菜的期间,她都还在你面前等着菜出来。
这样就浪费了很多内存资源,双11对电商服务器的压力可想而知。
而node是JS的运行环境,JS是单线程,通过异步编程,这样就不会有资源的浪费,就好比餐厅只有一个服务员,但是她可以一秒完成对你的服务,超级服务员(你大可不必在这里抬杠)。
你又可能会有疑问,那为什么我不多加几个厨师呢?
这就是服务器和数据库之间交流的硬件性能问题,数据库存放在硬盘中,硬盘的读取速度是取决于硬件的品质,是现实里存在的硬件,就会有提升的瓶颈,会有极限,而编程思想是没有限制的,同样一个任务的函数代码可以有不同的写法,道理是一样的。
又或者你可以直接理解成,刚开始的时候,js也就只是用来和浏览器打交道的,但是随着日益的需求,前端人员发现和后端交互的时候还不如自己写接口,于是乎,就有人发明了另外一种运行环境 node.js,你别在node这个英文单词上死钻牛角尖,没必要,你就知道这东西可以让你用js代码开发后端的相关的东西。
你需要理清这个概念,DOM,BOM这东西可不是js本身这门语言所有的,这可是浏览器环境提供给你更方便的开发页面效果的API。Node
说,既然我大哥浏览器环境都给你这么多API了,那我也给你一点吧。但是这里需要我们思想上有个转变,直接dom,bom都是和浏览器打交道,那些改变可以直观的在浏览器上展示出来,但是后端就是和数据打交道的,思想上要有转变,不能还按照之前前端的思想来思考这些问题了。
一.模块化思想
模块可以是一个.js
文件等一些东西,很抽象。由于我的学习过程是 三剑客-->react。所以我对es6的模块化比较熟悉,理解node中的这个也比较容理解接受。但是我们需要注意的是,node里遵循的是common.js规范,而我们浏览器端使用的是es6语法,node现在也可以完美支持es6的新的引入或者导出的规则,但是仍有不可代替的地方,比如import必须在头部引入,无法作为逻辑判断来进入函数内部。
比如if语言,你不可以这样编写你的代码
但是common.js却可以在逻辑判断中按需求引入。
1.2 模块的底层原理
我在nodeText文件夹下创建了两个文件
我们都知道,在我编写了一个js文件后,它就是可以被当作一个模块来使用,那我们在nodeOutPut里引入。
这里我们需要知道的是,require方法会将那个路径里的js文件内的代码编程成一个对象来引入。通过打印CCC的类型就可以知道其实是一个对象。这也就解释了为什么可以通过解构赋值的方法引入react的hooks
import {useState,useEffect} from 'react'
我们runcode
一下,可以看到控制台输出了我们在Text.js里编写的代码。
注意⚠️:特别重要的概念 在这个nodeText.js
模块里,node其实在外层包裹了一个函数,所以在这个里面定义的所有变量都是局部变量,这也就解释了为什么全局对象global
身上没有这两个属性。
arguments.calee
表示正在执行这个代码的参数,+" "
表示让arguments.callee这个被执行的函数toString
变成字符串拼接的形式打印出来,结果如下。
外壳的函数一共有五个参数
1.exports是module参数的一个属性,它和module.exports指向同一个对象地址,而module就是这个模块本身,module.exports.AAA= console.log(“a”)也就是暴露出去自己module身上的exports对象里的AAA方法。 2.require就解释了为什么你可以直接使用require这个方法而不需引入。 3._filename和_dirname很好理解,filenae精确到你这个本身,精确到index.js,而dirname精确到这个文件所在的文件夹。这就解释了为什么别的模块可以通过require('./nodeText')找到该模块。