ES6简介

ES6是2015年发布的一套JavaScript标准,基本上每年都有一个新版本

1、let&const

VSCode中,新建一个.html文件,输入!回车即可快速创建出一个html模板

1、let声明的变量有严格的局部作用域

1
2
3
4
5
6
7
8
9
10
<script>
// var 声明的变量往往会越域
// let 声明的变量有严格局部作用域
{
var a = 1;
let b = 2;
}
console.log(a);// 1
console.log(b);// b is not defined
</script>

因为b是在代码块中使用let定义的,所以在括号外打印会提示not defined

2、let声明的变量只能被赋值一次

1
2
3
4
5
6
7
8
<script>
var a = 1;
var a = 2;
let b = 10;
let b = 20;
console.log(a);
console.log(b);// Identifier 'b' has already been declared
</script>

var定义的变量,可以重新赋值,用let定义的变量不可以

3、let不会存在变量提升

1
2
3
4
5
6
<script>
console.log(a);// undefined
var a = 1;
console.log(b);// Cannot access 'b' before initialization
let b = 10;
</script>

使用var定义的变量没定义的时候会提升为undefined

使用let定义的变量没定义的时候会报错

4、const声明常量(只读变量)

1
2
3
4
5
6
7
8
9
<script>
const a = 1;
a = 3;// Assignment to constant variable.
</script>

<script>
const a;
a = 3;// Missing initializer in const declaration
</script>

const声明之后不允许改变,一但声明必须初始化,否则会报错

2、解构&字符串

1、可以批量将数组中的数据赋值给多个变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!--以前的写法-->
<script>
let arr = [1,2,3];
let a = arr[0];
let b = arr[1];
let c = arr[2];
console.log(a,b,c);// 1,2,3
</script>

<!--现在的写法-->
<script>
let arr = [1,2,3];
let[a,b,c] = arr;
console.log(a,b,c);// 1,2,3
</script>

2、可以批量将对象中的内容赋值给多个常量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<!--以前的写法-->
<script>
const person = {
name: "jack",
age: 21,
language: ['java', 'js', 'css']
}
const name = person.name;
const age = person.age;
const language = person.language;
console.log(name, age, language)
</script>

<!--现在的写法-->
<script>
const person = {
name: "jack",
age: 21,
language: ['java', 'js', 'css']
}
const{name,age,language} = person;
console.log(name, age, language)
</script>

<!--如果想将name、age、language赋值给新的变量abc 可直接赋值-->
<script>
const person = {
name: "jack",
age: 21,
language: ['java', 'js', 'css']
}
const { name: a, age: b, language: c } = person;
console.log(a, b, c)
</script>

3、字符串扩展

1
2
3
4
5
6
7
8
9
10
11
12
<script>
let str = "hello world";
// startsWith() 返回布尔值,表示参数字符串是否在原字符串的头部
console.log(str.startsWith("hello"));// true
console.log(str.startsWith("hello1"));// false
// endsWith() 返回布尔值,表示参数字符串是否在原字符串的尾部
console.log(str.endsWith("world"));// true
console.log(str.endsWith("world1"));// false
// includes() 返回布尔值,表示是否找到了参数字符串
console.log(str.includes("e"));// true
console.log(str.includes("a"));// false
</script>

4、字符串模板

1
2
3
4
5
6
7
<script>
// 可是使用``将一段字符串包含在里面 而不用像以前一样换行需要手动拼接字符串
let template =
`<div>
<span>hello world</span>
</div>`;
</script>

5、字符串插入变量和表达式或方法

1
2
3
4
5
6
7
8
9
10
11
<script>
const person = { name: "jack", age: 21 };
const { name, age } = person;
// 定义一个函数 返回你好啊
function say() {
return "你好啊";
}
// 可在``中写变量、对变量进行运算、同时可以调用函数
let str = `我叫${name},今年${age + 10}岁,${say()}`;
console.log(str);
</script>

3、函数优化

1、函数参数设置默认值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script>
// 在ES6以前,我们无法给一个函数的参数设置默认值
// 只能在代码中进行非空判断设置默认值
function add1(a, b) {
b = b || 1;
return a + b;
}
// 现在我们可以在参数上设置默认值
// 如果没有传则自动使用默认值
function add2(a, b = 1) {
return a + b;
}
console.log(add1(10), add2(10));// 11,11
</script>

2、传递不定参数

1
2
3
4
5
6
7
8
<script>
// 传入不定参数,打印参数的长度
function getLength(...values) {
console.log(values.length);
}
getLength(1, 2, 3);// 3
getLength(1, 2, 3, 4);// 4
</script>

3、箭头函数(可参考java8中的lamdba表达式)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!--定义一个参数-->
<script>
// 如果函数体只有一句话 可以简写成这种形式 通过=>连接
// print则为函数名 obj为参数名
var print = obj => console.log(obj);
print("hello");// hello
</script>

<!--定义多个参数-->
<script>
// 定义函数sum用于获取a+b的值
var sum = (a, b) => a + b;
console.log(sum(10, 20))// 30
</script>

<!--定义多个参数多行代码-->
<script>
// 定义函数sum用于获取a+b的值
var sum = (a, b) => { let result = a + b; console.log(result) };
sum(10, 20);// 30
</script>

<!--将解构和箭头函数整合在一起 直接将传入的person的name解构出传入函数-->
<script>
// 定义函数sum用于获取a+b的值
const person = { name: "Levi", age: 19 };
var hello = ({ name }) => console.log("名字是" + name);
hello(person);
</script>

4、对象优化

1、获取对象中的keys、values以及key-value

1
2
3
4
5
6
7
8
9
<script>
const person = { name: "Levi", age: 19 };
// 获取对象中的所有key数组
console.log(Object.keys(person));// ["name", "age"]
// 获取对象中的所有value数组
console.log(Object.values(person));// ["Levi", 19]
// 获取对象中所有的key-value数组
console.log(Object.entries(person));// 0: ["name", "Levi"],1: ["age", 19]
</script>

2、将一些对象复制到目标对象

1
2
3
4
5
6
7
8
9
10
<script>
const c1 = { a: 1 };
const c2 = { b: 2 };
const c3 = { c: 3 };
// 第一个参数为目标对象 将后面的参数值复制给第一个参数
Object.assign(c1, c2, c3);
console.log(c1);// {a: 1, b: 2, c: 3}
console.log(c2);// {b: 2}
console.log(c3);// {c: 3}
</script>

3、声明对象简写

1
2
3
4
5
6
7
8
<script>
const name = "Levi";
const age = 19;
// 如果名字和对象中的名字相同,则可以省略直接写
// const person = { name: name, age: age };
const person = { name, age };
console.log(person.name, person.age);
</script>

4、对象的函数属性简写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script>
let person = {
name: "Levi",
eat1: function (food) {
console.log(this.name + "正在吃" + food);
},
eat2: food => console.log(this.name + "正在吃" + food),
eat3(food) {
console.log(this.name + "正在吃" + food);
}
}
// 可以看出 箭头函数的写法是不支持this.name方法的
person.eat1("香蕉");// Levi正在吃香蕉
person.eat2("苹果");// 正在吃苹果
person.eat3("橙子");// Levi正在吃橙子
</script>

5、对象扩展运算符

1、拷贝对象(深拷贝)

1
2
3
4
5
6
<script>
let p1 = { name: "Levi", age: 19 };
// 使用... 将对象p1深拷贝到p2
let p2 = { ...p1 };
console.log(p2);// {name: "Levi", age: 19}
</script>

2、合并对象

1
2
3
4
5
6
7
8
<script>
let p1 = { a: 1, b: 2 };
let p2 = { b: 3, c: 4 };
// 将p1和p2的对象属性都合并到p3中
// 如果p1和p2有重复的属性 后面的覆盖前面的
let p3 = { ...p1, ...p2 };
console.log(p3);// {a: 1, b: 3, c: 4}
</script>

6、map&reduce

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script>
let arr = [1, 2, 3, 4, 5];
// 取出数组中的每一个数字 乘2后在返回一个数组
arr = arr.map(x => x * 2);
console.log(arr);// [2, 4, 6, 8, 10]
</script>

<script>
let arr = [1, 2, 3, 4, 5];
// 将上一次处理后的结果当作a 在加上b
// 返回本次a+b的值 即下一次的a的值
let result = arr.reduce((a, b) => a + b);
console.log(result);// 15
</script>

7、promise异步编排

新建一个json目录 其中包含如下三个json文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// user.json
{
"id": 1,
"name": "Levi"
}

// user_corse_1.json
{
"id": 10,
"name": "数学"
}

// course_score_10.json
{
"id": 10,
"score": "100分"
}

本地使用ajax依次查询出当前用户信息、用户课程信息、课程分数信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./node_modules/vue/dist/vue.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
</head>
<body>
<script>
// 定义一个方法 用于返回Promise
function get(url, data) {
return new Promise((resolve, reject) => {
$.ajax({
url: url,
data: data,
success(success) {
resolve(success);
},
error(error) {
reject(error);
}
})
});
}

// 调用get方法 获取用户信息
get("json/user.json").then(data => {
console.log("获取用户信息成功", data);
return get(`json/user_corse_${data.id}.json`);
}).then(data => {
console.log("获取用户课程成功", data);
return get(`json/course_score_${data.id}.json`);
}).then(data => {
console.log("获取课程分数成功", data);
})
</script>
</body>
</html>

8、模块化

模块化就是把代码进行拆分,方便重复利用,类似Java中的导包

要使用一个包,必须先导包,在JS中模块的含义就是包

模块功能主要由两个命令构成:exportimport

  • export命令用于规定模块的对外接口,可以导出一切js变量,比如:基本类型变量、函数、数组、对象
  • import命令用于导入其他模块提供的功能

例如:新建hello.js导出对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const util = {
sum(a, b) {
return a + b;
}
}

export { util }

// 也可以简写成如下格式
export const util = {
sum(a, b) {
return a + b;
}
}

例如:新建user.js导出变量和函数

1
2
3
4
5
6
7
var name = "Levi"
var age = 21

function getInfo(name, age) {
console.log(name, age);
}
export { name, age, getInfo }

新建一个main.js,导入hello.jsuser.js

1
2
3
4
5
6
7
// 可以只导入需要用的模块 不需要全部导入
import util from './hello';
import { name, age, getInfo } from './user';

util.sum(1, 2);
console.log(name, age);
getInfo("Homra", 12);

如果想要导入的时候自定义名字,可以在导出的时候使用default

1
2
3
4
5
6
7
8
9
// 我们可以将hello.js中的内容修改为如下
export default {
sum(a, b) {
return a + b;
}
}

// 这样我们导入的时候可以修改为任意名字导入
import homra from './hello';