ES6语法: 将之前的变量var改为了let, 常量为const. 为什么要改var呢?, 因为它有很多的坑...
//1. var允许重复声明变量而不报错:
var a = 10
var a = 20
console.log(a) //打印结果为20
//2. var 的作用域让人感到疑惑:
let b = "haha"
if (b == "haha"){
var age = 20
}
console.log(age) //是可以打印20的
换做let, 上面的两种情况就会报错, 而不是无脑输出
ES6 允许我们按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)
- 数组的解构赋值
const arr = [1, 2, 3] //我们得到了一个数组
let [a, b, c] = arr //可以这样同时定义变量和赋值
console.log(a, b, c); // 1 2 3
- 对象的解构赋值(常用)..具名参数
const obj = { name: '小龙',address:'北京', age: '100'} //我们得到了一个对象
let {name, age} = obj //可以这样定义变量并赋值
console.log(name, age); //小龙 100
- 函数参数的解构赋值(常用)
const person = { name: '小明', age: 11}
function printPerson({name, age}) { // 函数参数可以解构一个对象
console.log(`姓名:${name} 年龄:${age}`);
}
printPerson(person) // 姓名:小明 年龄:11
ES6 对函数增加了很多实用的扩展功能。
- 参数默认值,从ES6开始,我们可以为一个函数的参数设置默认值(这个默认值尽量放到后面)
function foo(name, address = '深圳') {
console.log(name, address);
}
foo("小明") // address将使用默认值
foo("小王", '上海') // address被赋值为'上海'
- 箭头函数,将function换成=>定义的函数,就是箭头函数
function add(x, y) {
return x + y
}
// 这个箭头函数等同于上面的add函数
(x, y) => x +y;
// 如果函数体有多行,则需要用大括号包裹
(x, y) => {
if(x >0){
return x + y
}else {
return x - y
}
}
由于js一开始被设计为函数式语言,万物皆函数。所有对象都是从函数原型继承而来,通过继承某个函数的原型来实现对象的继承。但是这种写法会让新学者产生疑惑,并且和传统的OOP语言差别很大。ES6 封装了class语法来大大简化了对象的继承。
nodejs里的class继承和java里的几乎一样
class Person {
constructor(name, age){ 构造函数就是这样写, 固定写法
this.name = name
this.age = age
}
// 注意:没有function关键字
sayHello(){
console.log(`大家好,我叫${this.name}`); //``在node里称为: 原生字符串
}
}
class Man extends Person{
constructor(name, age){
super(name, age)
}
//重写父类的方法
sayHello(){
console.log('我重写了父类的方法!');
}
}
let p = new Person("小明", 33) //创建对象
p.sayHello() // 调用对象p的方法,打印 大家好,我叫小明
let m = new Man("小五", 33)
m.sayHello() // 我重写了父类的方法!
NodeJS在用户代码层,只启动一个线程来运行用户的代码。每当遇到耗时的IO操作,比如文件读写,网络请求,则将耗时操作丢给底层的事件循环去执行,而自己则不会等待,继续执行下面的代码。当底层的事件循环执行完耗时IO时,会执行我们的回调函数来作为通知。
同步就是你去银行排队办业务,排队的时候啥也不能干(阻塞);异步就是你去银行用取号机取了一个号,此时你可以自由的做其他事情,到你的时候会用大喇叭对你进行事件通知。而银行系统相当于底层的事件循环,不断的处理耗时的业务(IO)。
所以Node非常适合进行Web开发 , 而不适合CPU密集型的计算操作
nodejs开放了js的能力, 让它可以访问文件, 读取数据库, 可以访问进程, 所以可以做后端
npm是nodejs的包管理工具, java之前用的是gradle, 相当于利用依赖库., 它的可用模块非常的多.
当我们想使用一个功能的时候,而node本身没有提供,那么我们就可以从npm上去搜索并下载这个模块。
npm install 包名
npm下载好的依赖, 保存到package.json
文件中
全局变量是指我们在任何js文件的任何地方都可以使用的变量。
__dirname
:当前文件的路径
__filename
:当前文件的绝对路径
console
:控制台对象,可以输出信息
process
:当前执行进程的对象,可以获取进程的相关信息,环境变量等
setTimeout/clearTimeout
:延时执行, 时间到了执行, 只执行一次
setInterval/clearInterval
:定时器,, 没隔一段时间执行一次
path模块供了一些工具函数,用于路径处理, 文件与目录的路径
path.basename
:返回(截取)一个路径的最后一部分
path.dirname
:返回一个路径的目录名
path.extname
:返回一个路径的扩展名(.js、.json等)
path.join
:用于拼接给定的路径片段
path.normalize
:将一个(不正常)路径正常化
console.log(path.normalize("F:/a\b\c/d")); //f:\a\b\c\d
10. 计算一段代码执行的时间
console.time("time") //这是开始计算时间
...... //要计算的代码块
console.timeEnd("time") //这是要计算的代码结束时间
这个名字可以随便起, 但是前后必须相同
http://nodejs.cn/api/fs.html
文件操作相关的模块, 看文档进行操作
fs.stat/fs.statSync
:访问文件的元数据,比如文件大小,文件的修改时间
fs.readFile/fs.readFileSync
:异步/同步读取文件
fs.writeFile/fs.writeFileSync
:异步/同步写入文件
fs.readdir/fs.readdirSync
:读取文件夹内容
fs.unlink/fs.unlinkSync
:删除文件
fs.rmdir/fs.rmdirSync
:只能删除空文件夹,思考:如何删除非空文件夹?
使用
fs-extra
第三方模块来删除。
fs.watchFile
:监视文件的变化
sync(很少用)是干什么的: 相当于同步, 阻塞直到完成
传统的
fs.readFile
在读取小文件时很方便,因为它是一次把文件全部读取到内存中;假如我们要读取一个3G大小的电影文件,那么内存不就爆了么?node提供了流对象来读取大文件。流的方式其实就是把所有的数据分成一个个的小数据块(chunk),一次读取一个chunk,分很多次就能读取特别大的文件,写入也是同理。这种读取方式就像水龙头里的水流一样,一点一点的流出来,而不是一下子涌出来,所以称为流。
let fs = require("fs");
// fs.readFile("MobyLinuxVM.vhdx", (err, data)=>{
// console.log(err);
// });
let reader = fs.createReadStream("MobyLinuxVM.vhdx");
let writer = fs.createWriteStream("MobyLinuxVM-copy.vhdx");
// let len = 0;
// reader.on('data', (chunk)=>{
// //chunk是每次读取到的一小块字节
// // console.log(chunk.length);
// // len += chunk.length;
// writer.write(chunk, ()=>{
// console.log("写入了一个chunk");
// })
// });
// reader.on('end', ()=>{
// console.log("读取完毕,总大小:"+len);
// });
//这叫做管道 大文件复制可以用pipe这个方式 比上面那个简单许多
reader.pipe(writer);