Node.js学习笔记-nodejs学习笔记

81 阅读4分钟

安装Node.js

很简单直接无脑下一步就可以了, 打开node的官网

下载后,双击安装包即可,然后无脑下一步,安装成功后,win+r,输入cmd,紧接着输入node -v 出现下面的情况就说明已经安装成功了 我们输入,node可以在终端直接进入Node的编写环境 例如我们输入

console.log("我爱你")

使用IDE进行编写代码

在这里我们使用微软的VS code,这款软件真的很推荐大家用,超级美丽 然后我们新建一个js文件,编写一段简单的js代码

class User {
    constructor(){
        this.username = "小明"
    }
}



var user1 = new User();

console.log(user1);

然后我们在VS code中自带的终端工具中,输入 node index.js 这时候我们的程序就会在node中进行运行,运行结果如下:

Node.js的导入和导出

Node.js采用的是CommonJs规范,在NodeJS中,一般将代码合理拆分到不同的JS文件中,每一个文件就是一个模块,而文件路径就是模块名。 在编写每个模块时,都有require、exports、module三个预先定义好的变量可供使用。 Node.js中模块的分类:

  • 核心模块(已经封装好的内置模块);
  • 自己定义的模块;
  • 第三方的模块(npm下载下来的);

require

require函数用来在一个模块中引入另外一个模块。传入一个模块名,返回一个模块导出对象。用法:let cc = require("模块名") ,其中模块名可以用绝对路径也可以用相对路径,模块的后缀名.js可以省略。例如:

let cc1 = require('./main.js')
let cc2 = require('home/src/main.js')
let cc3 = require('./main')

require()函数用两个作用:

执行导入的模块中的代码; 返回导入模块中的接口对象;

exports

exports对象用来导出当前模块的公共方法或属性,别的模块通过require函数使用当前模块时得到的就是当前模块的exports对象。用法:exports.name,name为导出的对象名。例子:

exports.add = function () {
  let i = 0
  console.log(++i)
}
​```
导出一个add方法供其他模块使用
其实exports类似于ES6中的export的用法,用来导出一个指定名字的对象。

> 上面是视频中老师的例子,我在这边举个例子

**index.js**
```js
//表示从index1.js中导入,在这里我们可以不写.js
//默认的后缀就是.js
let a = require('./index1.js');
console.log(a);

index1.js

let a = 123;

//表示我要导出的东西是,num,值为 a 的值
exports.num = a;

最后我们利用终端进行检测

node index.js

module

其实exports类似于ES6中的export的用法,用来导出一个指定名字的对象。

module.exports用来导出一个默认对象,没有指定对象名,常见于修改模块的原始导出对象。比如原本模块导出的是一个对象,我们可以通过module.exports修改为导出一个函数。如下:

module.exports = function () {
  console.log('hello world!')
}

重点:

  • exports其实就是指向module.exports
  • 系统默认设置了 exports= module.exports
  • exports只能设置单个的属性,例如exports.a = a
  • module.exports则可以设置对象属性,例如modules.exports = {name:"龙哥"}

模块的初始化

一个模块中的JS代码仅在模块第一次被使用时执行一次,并且在使用的过程中进行初始化,之后缓存起来便于后续继续使用。

主模块

通过命令行参数传递给NodeJS以启动程序的模块被称为主模块。主模块负责调度组成整个程序的其它模块完成工作。例如通过以下命令启动程序时,main.js就是主模块。

引入第三方的模块

这里我们以引入Jquery为例

  • 首先我们需要安装Jquery的依赖 在终端输入以下代码就可以安装Jquery
npm install jquery

安装成功后我们会在项目的目录中,发现 这里面放着我们所有第三方的Node的依赖

然后我们尝试把第三方的依赖引入进来

let $ = require('jquery');
console.log($);

成功!

那么现在我们要想想,这个原理是什么

首先当我们写下这段代码的时候

let $ = require('jquery');
  • node首先会在你文件同级的目录node modules文件夹中去寻找你后面写的东东,比如这里我们写的Jquery
  • 找到Jquery目录后,会去寻找目录中的package.json
  • 找到package.json后,会在这里面寻找,main这个属性 这个属性中就表明了Jquery这个依赖的主入口是在哪,比如这里就代表主入口就是dist/jquery.js
  • 然后通过上面的一系列操作,我们就成功将这个对象引入了

Node.js的读写操作

读操作

var fs = require('fs')
//同步的操作
// var content = fs.readFileSync('hello.txt',{flag:"r",encoding:"utf8"});
// console.log(content);

//异步的操作
fs.readFile('hello.txt',{flag:"r",encoding:"utf-8"},(err,data)=>{

    //如果存在错误,那么就将错误输出
    if(err){
        console.log(err);
    }else{
        //如果没有错误,那么就将data输出
        console.log(data);
    }

})

需要记住的就是,我们读操作两种方式,一种是同步的,一种是异步的,但是在真实开发的环境中,我们都是使用异步的方式来进行开发

写操作


fs.writeFile('zzm.txt',"你是谁啊",{encoding : 'utf-8',flag:'a'},(error)=>{

    if(error){
        console.log("失败")
    }else{
        console.log("成功")
    }

})

需要传入的参数为

  • 路径
  • 文本
  • option对象,在里面设置字符集以及flag flag为'a'表示append

buffer

为什么会有Buffer呢,也就是缓冲区,因为

  • js数组不能进行二进制操作
  • js数组不能像java、python那样的快速高效

所以就有了buffer

下面演示创建一个简单的Buffer

//安全的方式,但是每一次创建的时候会把缓存区的内容全部清空,效率会变慢
var buf2 = Buffer.alloc(10);

console.log(buf2);
//不安全的方式,只是指向一块空闲的缓存区
var buf1 = Buffer.allocUnsafe(10)

console.log(buf1);

可以看到我们的allocUnsafe()会更加快速

读取目录操作

fs.readdir('../day02',{encoding:'utf-8'},function(err,files){

    if(err){
        console.log(err);
    }else{
        files.forEach(async function(val,index){
            var content = await zmfs.readList('../day02/'+val);
            await zmfs.writeList('all.js',content);
        })
    }


})

我们可以封装两个常用的读取和写入文件的小工具 就给他取名叫做zmfs.js

let fs = require('fs');
//读取文件-
function readList(path){

    return new Promise(function(resolve,reject){
        
        fs.readFile(path,{flag:'r',encoding:'utf-8'},function(error,data){

            if(error){
                reject(error);
            }else{
                resolve(data);
            }

        })

    })
}
//写入文件
function writeList(path,content){
    return new Promise(function(resolve,reject){

        fs.writeFile(path,content,{flag:'a',encoding:'utf-8'},function(error){
            if(error){
                return reject(error);
            }else{
                return resolve(error);
            }
        })
    })
}

module.exports = {readList,writeList}

Node.js的输入输出

node.js中也有可以交互的输入和输出,让我们来看一段相应的实例,就能明白其中的道理

const { stdin, stdout } = require('process');
/**
 * 练习使用输入输出
 */

 //首先导入模块
 let readline = require('readline');
//创建接口
const r1 =  readline.createInterface({
     input:process.stdin,
     output:process.stdout
 })
 //开始方法
 r1.question("你的名字是什么?",function(answer){
    console.log("答复:"+ answer);
    r1.close();
 })

 r1.on('close',function(){
    process.exit(0);
 })

那我们可以做一个小练习,就是根据问题去输入答案,然后将文档输出

const zmfs = require('./zmfs')
/**
 * 练习使用输入输出
 */

 //首先导入模块
 let readline = require('readline');
//创建接口
const r1 =  readline.createInterface({
     input:process.stdin,
     output:process.stdout
 })
//创建问题的方法
function createQuestion(question){
    return new Promise(function(reslove,reject){
        r1.question(question,function(answer){
            reslove(answer);
         })
    })
}
 //开始方法
async function createFile(){
    let author = await createQuestion("作者?");
    let name = await createQuestion("书名?");
    
    let content = `
        "书名" : ${name},
        "作者" : ${author} 
    `;


    //注意这里也是一个异步操作

    await zmfs.writeList('book.txt',content);

    r1.close();

}


createFile();

 r1.on('close',function(){
    process.exit(0);
 })

最后我们可以看到boot.txt