ECMAScript
ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准
ECMAScript 是 JavaScript 语言的规范
JavaScript 是 ECMAScript 语言的实现
- 具体实现要看浏览器的内核
ES2015 和 ES6 是一样的
Babel转码器
Babel是一个广泛使用的ES6转码器,可以将ES6代码转为ES5代码
配置文件
Babel的配置文件是.babelrc
,存放在项目的根目录下presets
字段设定转码规则
1 | { |
let和const
let
- 变量提升
- 作用域
- 再同一个块级作用域,不能声明同名的变量
- 暂时性死区Code
1
2
3
4
5
6
7var tmp = 123;
if(true){
// 通过let声明的变量会绑定当前块级区域
// 只能先声明再使用
tmp ="abc";
let tmp;
}
const
const声明的是一个不变的量,叫做常量
声明的同时,必须初始化,一旦声明则不允许修改,否则报错
其他的跟Let一样
注意:引用类型定义的是存放的地址,其里面的值是可以修改的
数组结构赋值
以前:
1 | let a = 1; let b = 2; |
ES6:可以从数组中提取值,按照对应位置,对变量赋值。
本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。下面是一些使用嵌套数组进行解构的例子。
1 | let [x,y] = ["a","b"]; // x=a,y=b |
如果结构不成功,变量值都会等于undefined
1 | let [foo] = []; |
另一种情况是不完全解构,即等号左边的模式,只匹配一部分的等号右边的数组。这种情况下,解构依然可以成功
1 | let [x, y] = [1, 2, 3]; |
默认值:
1 | let [foo = true] = []; // foo = true |
上面代码中,如果一个数组成员是null,默认值就不会生效,因为null不严格等于undefined。
对象的默认值
1 | function ajax(url,{ |
字符串的扩展
常用方法
includes(str) 返回布尔值,表示是否找到了参数字符串
startWith(str) 返回布尔值,表示参数字符串是否再源字符串的头部
endsWith(str) 返回布尔值,表示参数字符串是否再源字符串的尾部
repeat(n) 返回一个新字符串,表示将原字符串重重n次
模板字符串
以前
1 | let name = "jack"; |
现在
1 | let name = "jack"; |
数值的扩展
ES6 将全局方法parseInt,parseFloat,isNaN,isFinite,isInteger
到挂在到了Number对象上,以后使用都将加上Number.
的前缀
数组的扩展
- Array.from() 将伪数组装换成真数组
- 伪数组:首先是个对象,有length属性切部位0,必须是num类型的
- Array.of() 创建一个数组
- Array(3)是创建了一个length为3的数组,Array.of(3)是创建了一个数组值为[3]
- find()
- 找出第一个符合条件的成员
- findIndex()
- 找出第一个符号条件的索引值
- includes(str)
- 是否包含str
- for…ofCode
1
2
3
4
5
6
7
8
9
10
11
12for(let index of arr.keys()){
console.log(index); // 拿到索引值
}
for(let item of arr.values()){
console.log(item) // 拿到每一项
}
for(let [index,item] of arr.entries()){
console.log(index,item); // 两者的结合
}
函数的扩展
函数的默认值
Code1
2
3
4
5
6
7
8
9
10以前:
function fn(a,b){
let a = a || "hello";
let b = b || "world"
}
现在:
function fn(a = "hello",b = "world"){
}rest参数
- 将将函数多余的参数转换为一个数组Code
1
2
3
4function num(...aa){
console.log(aa) // [1,2,3]
}
num(1,2,3)
- 将将函数多余的参数转换为一个数组
扩展运算符
- 将一个数组/对象展开
- 可以替换apply写法Code
1
2
3
4
5
6
7
8
9let arr = [1,2,3,4]
console.log(...arr) // 1 2 3 4
function aa(x,y,z){
console.log(x,y,z)
}
aa.apply(null,arr)
aa(...arr)
箭头函数
- 会把this指向当前的作用域,使用的是定义时的this,而不是使用时的this
- 不能作为构造函数
- 不能使用arguments,用…rest
- 他的一个缺点是:在底下声明,在上面不能调用。没有变量提升
对象的扩展
属性的简洁表示法
- 当属性名跟变量名一样时,可以简写Code
1
2
3
4let [aa,bb] = [11,22];
let obj = {aa,bb};
console.log(obj) // {aa: 11,bb: 22}
- 当属性名跟变量名一样时,可以简写
getter和setter
1 | let aa = { |
- 属性的便利
- for…in
- Object.keys() 返回一个对象的所有键名
导入对象和导出对象
- import可以导入对象,用法:
- import 变量接收名 from “包的名称 | 包的路劲”
- import “包的名称 | 包的路劲”
- 导出对象
- export default {}
- 一个模块中只能导出一次
- 在一个模块中可以同时使用export default 和 export
- export var title = “”
- 只能用{}的方式来接收
- 导出时什么名字接收时就用什么名字
- 如果想换个名字接收则可以使用as关键字
- import { title as tt } form “module”
- 如果想用一个变量导出所有成员也可以使用as关键字
- import * as all from “module”
- export default {}
面对对象
老的面对对象写法:
1 | function Person(arg){ |
ES6写法:
1 | class Person { |
两种写法的结果都是一样的,但是ES6的写法看起来会更加的舒服
ES6中的继承写法:
1 | class Person { |
ES6中的继承是通过extends关键字来实现
class 子类 extends 父类
,
继承了之后就必须调用super方法
Set和Map
Set
和Map
主要的应用场景在于数组去重和数据存储
集合
集合是由一组无序且唯一(即不能重复)的项组成的,可以想象成集合是一个既没有重复元素,也没有顺序概念的数组
ES6提供了新的数据结构Set。它类似于数组,但是成员的值都是唯一的,没有重复的值
ES6提供了新的数据结构Set。它类似于数组,但是成员的值都是唯一的,没有重复的值
Set 本身是一个构造函数,用来生成 Set 数据结构
这里说的Set其实就是我们所要讲到的集合,先来看下基础用法
1 | const s = new Set(); |
Set实例的属性和方法
Set的属性:
- size: 返回集合所包含元素的数量
Set的方法:
add(value):像集合添加一个新的项
delete(value):从集合中移除一个值
has(value):如果值在集合中存在,返回true否则false
clear():移除集合里所有的项
keys():返回一个包含集合中所有键的数组
values():返回一个包含集合中所有值的数组
entries:返回一个包含集合中所有键值对的数组
字典
在数据结构还有一种结构叫做字典,它就是实现基于ES6中的Map类的结构
那么集合又和字典有什么区别呢:
- 共同点:集合、字典可以存储不重复的值
- 不同点:集合是以[值,值]的形式存储元素,字典是以[键,值]的形式存储
所以这一下让我们明白了,Map其实的主要用途也是用于存储数据的,相比于Object只提供“字符串—值”的对应,Map提供了“值—值”的对应。也就是说如果你需要“键值对”的数据结构,Map比Object更合适
下面来看一下基本使用:
1 | const m = new Map(); |
属性:
- size:返回字典所包含的元素个数
方法:
set(key,val):向字典中添加新元素
get(key):通过键值找特定的数值并返回
has(key):如果键存在字典中返回true否职责false
clear():将这个字典中的所有元素删除
keys():将字典中包含的所有键名以数组形式返回
values():将字典中包含的所有数值以数组形式返回
Promise
Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。
具体用法:
- 这里是封装了一个readFile的方法Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16const _readFile = (path) => {
return new Promise((resolve,reject)=>{
fs.readFile(path,"utf8",(err,data)=>{
if (err){
throw new Error("请求未成功")
}else {
resolve(data);
}
})
})
}
_readFile(contactsPath)
.then((data)=>{
console.log(data);
})
Promise.all
Promise.all可以将多个Promise实例包装成一个新的Promise实例。同时,成功和失败的返回值是不同的,成功的时候返回的是一个结果数组,而失败的时候则返回最先被reject失败状态的值。
1 | let p1 = new Promise((resolve, reject) => { |
Promise.race
顾名思义,Promse.race就是赛跑的意思,意思就是说,Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。
1 | let p1 = new Promise((resolve, reject) => { |
async和await
async function
用来定义一个返回Async function
对象的异步函数,异步函数是指通过事件循环异步执行的函数,他会通过一个隐式的Promise
返回其结果,如果你再代码中使用了异步函数,就会发现他的语法和结构会更像是标准的同步函数
await操作符用于等待一个Promise对象,它只能再异步函数async function
中使用
1 | function fun(){ |
Fetch
Fetch API 提供了一个 JavaScript 接口,用于访问和操纵 HTTP 管道的一些具体部分,例如请求和响应。它还提供了一个全局 fetch() 方法,该方法提供了一种简单,合理的方式来跨网络异步获取资源。
Fetch不能跨域,第一个.then
返回的是status和url等数据,要想拿到传输过来数据,第一个.then
要return res.json()
- 用法:Code
1
2
3
4
5
6
7fetch('http://example.com/movies.json')
.then(function(response) {
return response.json();
})
.then(function(myJson) {
console.log(myJson);
});
ES6新语法
赋值
- 数组结构赋值
- let a = 1,b = 2,c = 3;
- ES6: let [a,b,c] = [1,2,3];
- 对象的结构赋值
- let {foo,bar} = {foo: “hello”,bar: “hi”}
- 对象属性别名(如果有了别名,那么原来的明治就无效)
- let {foo:abc,bar} = {foo: “hello”,bar: “h1”}
- console.log(abc) // hello
- console.log(foo) //undefined
- let {foo,bar} = {foo: “hello”,bar: “hi”}
- 字符串的结构赋值
- let [a,b,c,d,e] = “hello”;
- 就跟let [a,b,c,d,e] = [‘h’,’e’,’l’,’l’,’o’];一样
- 数组结构赋值
字符串扩展
常用方法
- includes(str,index)
- 判断字符中是否包含指定的字符,放回Boolean
- arguments1:匹配的字符串,arguments2:从第几个开始匹配
- stratsWith(str)
- 判断字符串是否以特定的字符串开始
- endWith(str)
- 判断字符串是否以特定的字符串结束
- includes(str,index)
模板字符串(反单引号)
str
Code1
2
3let obj = {name:'zz',age:'19'}
console.log(`my name is ${obj.name}`)
console.log(`${obj.age} years old this year`)
函数扩展
参数默认值
- function foo(param = “hello”){}
参数结构赋值
- function foo({uname,age}={uname:”zz”,age:20})
- 调用是赋值是 foo({uanme:’zz’,age:10})
rest参数(…)
- Code
1
2
3
4
5function foo(a,b,...param){
console.log(a,b,param);
}
foo(1,2,3,4,5)
result: a = 1,b = 2,param = [3,4,5];
扩展运算符(…)
Code1
2
3
4
5
6function foo(a,b,c,d,e){
console.log(a+b+c+d+e);
}
let arr = [1,2,3,4,5]
foo(...arr);
result: 15箭头函数
- 箭头函数中的this取决于函数的定义,而不是调用
- 箭头函数不可以new
- 箭头函数不可以使用arguments获取参数列表,可以使用rest来代替
类与继承
- 以前写法:
Code1
2
3
4let Person = (name) => {
this.name = name;
}
Person.prototype.showName = () => { console.log(this.name); }- 现在写法
Code1
2
3
4
5
6
7
8
9
10
11
12
13
14
15class Person {
// 静态方法(只有通过类名来调用,不能用实例对象来调用)
static showInfo(){
console.log('hi');
}
// 构造函数
constructor(name) {
this.name = name;
}
showName(){
console.log(this.name)
}
}- 继承写法
Code1
2
3
4
5
6
7
8
9
10class now extends Person {
constructor(name,color){
super(name); // super调用父类
this.color = color;
}
showColor(){
console.log(this.color);
}
}
### queryString
+ queryString.parse(str);
* parse方法的作用就是把字符串转换成对象
+ queryString.stringify(obj)
* 作用就是把对象转换成字符串
- request.method
- 获取当前请求的方式