node(一)
标签(空格分隔): 前端笔记
const path = require('path');
const fs = require('fs');
//记住,今后只要涉及到路径片段的拼接,一定要使用path.join()方法
// __dirname 是运行js文件的那个目录文件夹
fs.readFile(path.join(__dirname,'./22.txt'),'utf-8',(err,data) => {
if (err){
console.log(err);
} else {
console.log(data);
}
})
结论:今后在调用 fs 模块,操作文件的时候,如果要提供路径,一定不要使用相对路径。
js代码什么情况下必须加分号
如果一行代码,是以{ [ + - /
这5个符号中的任何一个开头,则应该在行首,添加一个分号
;[1,2,3].forEach(item=> {
console.log(item);
})
- 读取文件的方法
fs.readFile(__dirname + '/files/1.txt','utf-8',(err,data)=> {
if (err) {
return console.log("读取文件失败"+err.message);
}else {
console.log(data);
}
})
- 文件写入的方法
const fs = require('fs');
fs.writeFile('./files/2.txt','abcdd',(err)=> {
if(err){
console.log("写入文件失败!"+err.message);
}else{
console.log('写路文件成功!');
}
})
- 追加文件
const fs = require('fs');
fs,appendFile('./files/2.txt','4444',(err) => {
if(err){
return console.log('追加失败!'+err.message);
}else{
console.log('ok!');
}
})
1、整个node.js课程学习目标
- 【基础概念】
- 什么是node.js以及node.js的特点
- node.js适合做什么
- 什么是模块化、什么是Common.js模块化规范
- 模块、包、npm、包加载机制
- etc
- 【基本能力】
- 掌握node.js中基本API的使用
- 能够使用npm包管理
- 能够使用ES6新语法
- 能够使用node.js创建基本的Web服务器
- 【高阶能容】
- 能够使用Express框架、结合mysql数据库实现后端网站
- 把做好的网站部署到服务器中,供外网访问
- 把做好的网站,使用https协议对外发布
注意:整个node.js学习阶段,概念类知识点较多,需要理解透彻!
总结:node.js整个课程阶段,最主要的学习目标,是为了能够使用node.js,结合JavaScript实现后端编程。
2、了解基本概念
2.1 语言和环境(平台)之间的关系
语言,是编写代码的语法规范;程序员遵循特定的语法规范,编写出来的代码,只是单纯的文本字符串而已,并不具备可执行的特点。
环境(平台),提供了执行代码的能力,如果程序员编写的代码想要成功执行,必须要特定的执行环境
- 例如:JavaScript代码可以被浏览器中的JS解析引擎执行;
- 所以,浏览器,就是一个JavaScript的执行环境,因为JavaScript代码可以在浏览器中被执行。
- 我们即将要学习的node.js,就是另外一个JavaScript解析执行环境,所以,JavaScript代码,还可以运行在node.js中。
2.2 前端和后端
- 后端主要工作
- 操作数据库
- 对外暴露操作数据库的API接口
前后端写作开发
前端主要工作
- 美化页面样式
- 页面结构
- 书写页面的业务逻辑
- 使用Ajax调用后台接口
2.3 浏览器环境中的Javascript
- 诞生:上世纪90年代左右,网景liveScript、表单验证
- 一战:
- 主角:微软和网景
- 结果:微软IE胜出
- 胜利的果实:ECMAScript语言标准的诞生
- 二战:
- 主角:谷歌、火狐、IE
- 结果:谷歌胜出
- 胜利的果实:谷歌的V8引擎是最快的JS解析引擎
- 回顾:浏览器中JavaScript的组成部分
- ECMAScript核心+DOM+BOM
2.4 NOde环境中的JavaScript
- 什么是node.js:就是JavaScript的服务器端运行环境,可以让程序员使用JavaScript来实现服务端的编程
- node.js中的JavaScript的组成部分
- ECMAScript 核心 + 全局成员 + 核心API模块
- 全局成员
- 核心 API模块:就是node平台单独提供的一些api,这些api都是node平台所独有的
- 注意:node.js中没有BOM、DOM
- 由于node服务器端运行环境中,没有浏览器和HTML的概念,所以,node中的javascript提出了DOM和BOM这两个对象模型,取而代之的,是全局成员和核心API模块。
2.5 ECMAScript规范,浏览器中的Js,node中的js之间的关系
- ECMAScript规范(标准):就是一本书,这本书中规定了语言的特性
- 浏览器中的js:
- 浏览器中的js组成部分,ECMAScript核心 + DOM + BOM
- node中的js
- node中的js组成部分:ECMAScript核心 + 全局成员 + 核心API成员
2.7 总结
- 什么是node.js(我们自己给它下个定义)
就是一个服务器端的JavaScript运行环境,可以让程序员,通过JavaScript做后台服务器编程开发。
- 学习node.js可以做什么
- 像PHP一样,使用JavaScript编写符合规范的后端API接口或带后台功能的网站
- 使用node.js开发一些实用的工具或包
- 基于Socket技术,开发类似聊天室之类的即时通讯项目
- 基于Electron环境,开发桌面软件
- ect...
3、环境安装
3.1 LTS和Current版本的区别
- LTS:【推荐在企业中使用】,是长期稳定版的安装包,运行稳定、安全
- Current:【推荐学习或尝鲜去使用】,是最新特征版,这个安装包中有最新的node特性。
3.2 下载安装
官网:[node.js官网][1]
查看是否安装成功:
cmd ---- > node -v
3.3 查看node版本号
- 打开终端,在命令行输入命令node -v即可
- Tips:如何进入终端呢?
- 【推荐】在任意目录的空白位置,先按住shift键不松开,然后在空白位置,鼠标右键档级,会出现一个右键菜单,选择在此处打开 powershell/cmd窗口
- 【了解】使用快捷键windows徽标 + R打开运行面板,输入cmd后直接回车
3.4 path环境变量
- 什么是环境path环境变量
- path环境变量的作用:能够让我们在终端中执行相关的命令,从而快速启动应用程序
- 系统环境变量和用户环境变量的区别
- 用户环境变量:
- 系统环境变量:
- 通过终端输入命令的形式,快速启动应用程序时,路径的查找规则
- 先在当前运行终端命令的目录中查找,如果有则直接运行;
- 如果当前目录中没有,则去全局的path环境变量中查找
4、node.js环境中执行js代码的两种方式
4.1 node 命令(推荐)
- 直接使用node要执行的js文件的路径来执行指定的的JS文件
小技巧:
1. 在终端中,使用的键盘的上键,可以快速定位到上一次执行的命令
2. 在终端中,使用键盘的tab键能够快速补全路径
3. windows系统上,在终端中输入cls可以清屏
4. 可以使用exit命令退出当前终端
创建一个js文件:
在文件的目录中打开终端:
node ./11.js
4.2 REPL环境-了解
- 如何进入REPL环境,打开任意终端,直接输入node并回车,就会进入到REPL环境中
- 如何离开REPL环境,按两次 ctrl + c 就能退出REPL环境
- REPL中,每个字母代表什么意思呢:
- R:Read的意思,每当我们输入完毕代码之后,只要敲击回车,node环境就会读取用户输入的代码
- E:Evalute的意思,表示把read进来的用户代码,调用类似于Eval的函数,去解析执行
- P:Print输出的意思,把第二步中解析执行的结果,输出给用户
- L:Loop循环的意思,表示当输出完毕之后,进入下一次REPL循环
5、ECMAScript 6常用的语法
5.1 let(变量)与const(常量)
- 之前定义变量,用var关键字,有如下主要特点:
- 存在变量提升问题,降低js代码的可阅读性
- 没有块级作用域,容易造成变量污染
- 变量可以被多次重复定义
- let主要特征
- 不存在变量提升问题,只有定义之后才能使用此变量
- 有
{ }
作用域,而且,在同一作用域中,无法重复定义
- const主要特征
- 不存在变量提升问题,只有定义之后才能使用此变量
- const定义的常量,无法被重新复制
- 当定义常量的时候,必须定义且初始化,否则报语法错误
- const定义的常量,也有块级作用域
console.log(a); //-->不报错,输出undefind
var a = 10;
// let也是用来定义变量的
console.log(a); //--> 报错,变量没有声明
let a = 10;、
/*------------------------*/
for(var i = 0;i < 3;i++ ){ }
console.log(i); //--> 输出为3 3,循环之后输出为3,var没有块级作用域
for(let i = 0;i<3;i++){ }
console.log(i); //--> 报错,let声明的变量具有块级作用域,只有在for循环中才可以访问到,在外部访问报错
/*------------------------*/
for(let i = 0;i<3;i++){
// 由于 { }会对let产生作用域,所以每次循环,都创建了独立的 {} 的作用域,和上一次的循环,作用域各自独立
console.log(i); //--> 输出为:1、2、3 每个for循环都是一个块级作用域,循环三次,创建三个块级作用域
}
/*------------------------*/
var a = 10 ;
var a = 20 ;
console.log(a); //--> 输出为20,var 可以重复声明一个变量
{
let a = 10;
let a = 20;
console.log(a); //--> 报错,在同一作用域中,let定义的变量,无法被重新定义
}
var a = 30;
console.log(a); //--> 在不同作用域中,可以使用let定义相同的变量名
/*------------------------*/
const a;
console.log(a) //--> 报错,定义const常量时候,必须定义且赋值
5.2 变量的结构赋值(常用)
定义:所谓的结构赋值,就是把某个对象中的属性,当作变量,给解放出来,这样,今后就能够当作变量直接使用了。
- 可以使用:为解放出来的变量重命名
//变量的结构赋值
const obj = {
a: 10,
name: 'zs'
}
//可以直接通过 = 为常量对象中的属性赋值,但是无法使用 = 为常量重新赋值
obj.a = 20;
console.log(obj);
/*--------------------------*/
const person = {
name: 'zs',
age: 22,
gender: '男',
address: '成都'
}
//传统做法
const name = person.name;
console.log(name);
const address = persobn.address;
console.log(address);
//结构赋值
const { name:username,address:address } = person //把对象的name属性和address属性的值取出来
console.log(name);
console.log(address);
5.3 箭头函数
- 语法
- 定义普通的function函数
function show() {
console.log('这是普通 function 定义的 show 方法');
}
- 把方法定义为箭头函数(最完整的写法)
(形参列表) => {函数体代码}
箭头函数,本质上就是一个匿名
箭头函数的特性:箭头函数内部的this,永远和箭头函数外部的this保持一致
变体
- 变体1:如果箭头函数,左侧的形参列表中,只有一个参数,则,左侧小括号可以省略
- 变体2:如果右侧函数中,只有一行代码,则,右侧的 { } 可以省略
- 变体3:如果箭头函数左侧只有一个形参,而且右侧只有一行代码,则两边的 () 和 { } 都可以省略
- 注意:如果我们省略了右侧函数体的 {} ,那么,默认会把右侧函数体中代码的执行结果,当作箭头函数的调用结果return 出去。
const show = (name)=> {
console.log('my name is'+ name);
}
show('zs');
//箭头函数的自调用
;(()=> {
console.log('my name is'+ name);
})();
//变体1(省略() )
const show = name=> {
console.log('my name is'+ name);
}
//变体2 (省略 {})
const show = (name)=> console.log('my name is'+ name);
//变体3 (省略 ()和 {})
const show = name => console.log('my name is'+ name);
5.4 对象中定义方法和定义属性的便捷方式
const name = 'zs';
const age = 22;
const gender = '女';
const say = function(){
console.log('say');
}
const person = {
name,
age,
gender,
say,
show(){
console.log(this);
}
}
6、文件操作
6.1 文件读取
/*
* 使用 require 方法,导入fs模块
* fs模块的作用,就是来操作文件的
*/
const fs = require('fs');
/*
* 接收三个参数
* 参数1:【必选参数】字符串的文件路径,表示要读取哪个文件
* 参数2:【可选参数】字符串类型的编码格式,默认为null
* 参数3:【必选参数】回调函数
* 有两个参数 err 错误的结果 data 读取到的内容
*/
fs.readFile('./files/1.txt',(err,data)=> {
// 如果读取成功,则 err 为 null,data 是成功之后的数据
// 如果读取失败,则err 为一个错误对象,data 为undefined
// err 是Error类型的一个对象,data 是一个二进制的数据,不过在展示的时候,为了方便展示,操作系统帮我们把二进制的 Buffer 转换为了十六进制的格式
console.log(err); //--> null
console.log(data); //--> <Buffer 61 62 63>
/*---------------------------------*/
console.log(data.toString());
});
/*---------------------------------*/
//提供了编码格式自动转换为二进制,没有提供编码格式则直接显示二进制
fs.readFile('./files/1.txt','utf-8',(err,data)=> {
console.log(data);
})
/*-----------------------------------------使用此方法*/
fs.readFile('./files/1.txt','utf-8',(err,data)=> {
if (err) {
return console.log("读取文件失败"+err.message);
}else {
console.log(data);
}
})
6.2 文件写入
const fs = require('fs');
/*
*参数1:要把文件写路到哪个路径中
*参数2:要写入的内容
*参数3:字符集编码格式
*参数4:回调函数,只有一个参数err
* 如果文件存在,则会覆盖文件
*/
fs.writeFile('./files/2.txt','abcdd',(err)=> {
if(err){
console.log("写入文件失败!"+err.message);
}else{
console.log('写路文件成功!');
}
})
6.3 文件追加
const fs = require('fs');
/*
*参数1:要追加的文件
*参数2:追加的内容
*参数3:字符集编码,默认为utf-8
*参数4:回调函数,参数为err
* 如果追加的文件不存在,就会创建这个文件
*/
fs,appendFile('./files/2.txt','4444',(err) => {
if(err){
return console.log('追加失败!'+err.message);
}else{
console.log('ok!');
}
})
6.4 fs模块中路径操作问题(难点)
console.log(__dirname); //--> 打印出文件所在的目录 C:\Users\19254\Desktop\node
console.log(__filename); //--> 打印出文件所在的路径以及文件名称 C:\Users\19254\Desktop\node\11-fs.js
/*-------------------------------*/
6.5 读取文件信息
const fs = require('fs');
//读取文件信息
const fs = require('fs');
fs.stat(__dirname+'/22.txt','utf-8',(err,stats) => {
if (err){
console.log("读取文件失败!" + err.message);
} else {
//读取文件大小,单位是子节 byte(不能获取目录的大小)
console.log(stats.size);
//读取文件的创建时间
console.log(stats.birthtime);
//判断是否是一个文件
console.log(stats.isFile());
//判断是否是一个目录
console.log(stats.isDirectory());
}
})
6.6 读取指定目录中所有文件的名称
/*
* 第一个参数要复制的文件路径
* 第二个参数要存放的文件路径
* 第三个参数回调函数,参数是错误对象
* */
fs.copyFile(__dirname+'/22.txt',__dirname+'/22-copy.txt',(err) =>{
if (err){
console.log("复制文件失败!"+err.message);
} else {
console.log("复制成功!");
}
});
7、路径操作
- path.sep
const path = require('path');
/*
* 提供平台特定的路径片段分隔符
* windows 上是 '\'
* posix 上是 '/'
* */
console.log(path.sep); //--> \
- path.basename(pathname [,ext])
const path = require('path');
const pathStr = "c:/a/b/c/1.html";
//返回最后文件名字以及后缀名
console.log(path.basename(pathStr)); //--> 1.html
//传第二个参数,就是文件的后缀名,输出的话就会忽略文件的后缀名
console.log(path.basename(pathStr,'.html')); // --> 1
- path.dirname(pathname)
const path = require('path');
//创建一个文件路径
const pathStr = "c:/a/b/c/1.html";
//获取文件所在的目录
console.log(path.dirname(pathStr));// -->c:/a/b/c
- path.extname(pathname)
const path = require('path');
//创建一个文件路径
const pathStr = "c:/a/b/c/1.html";
//获取文件的扩展名
console.log(path.extname(pathStr)); // --> .html
- path.join([...paths])
const path = require('path');
const result = path.join('c:/','a/b','/c','/d','../11.js');
console.log(result); // --> c:\a\b\c\11.js