Es6-Es11
let
-
变量不能重复生命
1
2let star = 'start'
let star = 'start' // error -
块儿级作用域
1
2
3
4
5
6
7{
let star = 'start'
}
console.log(star) // error
// if else while for -
不存在变量提升
1
2console.log(start) //error
let start = 'star' -
不影响作用域链
1
2
3
4
5
6
7{
let star = 'star';
function outStar() {
console.log(star);
}
outStar();
} -
案例练习
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
<style>
.app ul li {
display: inline-block;
width: 100px;
height: 50px;
border: 2px solid skyblue;
}
</style>
<div class="app">
<ul>
<li class="item"></li>
<li class="item"></li>
<li class="item"></li>
</ul>
</div>
<script>
const items = document.querySelectorAll('.item');
for (let item = 0; item < items.length; item++) {
console.log(item);
items[item].onclick = function () {
items[item].style.background = 'blue';
};
}
// let 为 var 时,item结果为 3 , 无法执行内部函数
console.log(window.item);
</script>
const
- 定义常量
- 一定要赋初始值
- 潜规则变量大写
- 块级作用域
解构
-
Es6
允许按照一定模式从数组和对象中提取值, 对变量进行赋值, 这被称为 解构赋值
-
数组解构
1
2
3
4
5
6// 数组的解构
const ARRAR = ['A', 'B', 'C'];
// a,b,c 就是数组元素对应的值
let [a, b, c] = ARRAR;
console.log(a);
console.log(b); -
对象解构
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21let coderitl = {
name: 'coderitl',
age: '不详',
study() {
console.log('正在学习es6...');
}
};
// 简化对象值的获取
let { name, age, study } = coderitl;
console.log(name); // coderitl
console.log(age); // 不详
console.log(study); // 正在学习es6...
study() // 函数调用
// 对象的属性获取,解构可以简化如下操作
coderitl.name
coderitl.age-
输出
解构对象
-
模板字符串
-
声明
1
2let str = `aa`
console.log(str,typeof str); -
内容中可以直接出现换行符
1
2
3
4
5let str = `
<ul>
<li></li>
</ul>
`; -
拼接变量
1
2
3let name = `coderitl`;
let cd = `${name}正在学习 Es6`
console.log(cd);
对象简写
-
Es6
允许在大括号里面, 直接写入变量和函数, 作为对象的属性和方法 1
2
3
4
5
6
7
8
9let name = 'coder-itl';
let change = function () {
console.log('我们改变你!');
};
const info = {
name,
change,
};
console.log(info);-
输出对比
对象简写
-
箭头函数
-
声明
1
2
3
4
5
6
7
8
9
10
11// 普通函数
let userName1 = function(){
console.log('coder-itl-1');
}
// 箭头函数
let userName2 = ()=>{
console.log('coder-itl-2');
}
// 函数调用
userName1()
userName2() -
特性
-
this
是静态的, this
始终指向函数声明时所在作用域下的 this
的值 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18let userName1 = function () {
console.log('coder-itl-1');
console.log('userName1:',this.name);
};
let userName2 = () => {
console.log('coder-itl-2');
console.log('userName2:',this.name);
};
window.name = 'global coder-itl';
const school = {
name: '育才中学'
};
userName1();
userName2();
console.log('------------');
userName1.call(school)
userName2.call(school)-
输出对比
this
指向
-
-
不能为构造函数实例化
1
2
3
4
5
6let Person = (name, age) => {
this.name = name;
this.age = age;
};
let person = new Person();
console.log(person);-
输出
箭头函数不能为构造函数实例化
-
-
不能使用
arguments
变量 arguments
-
rest 参数
-
使用
1
2
3
4function date(...args) {
console.log(args);
}
date('A', 'B', '白芷');-
输出
rest
参数 -
注意: 在有其他参数时,
该参数必须放在最后
-
扩展运算符
-
...
扩展运算符能将 [数组]
转换为逗号分隔的 参数序列
-
使用
1
2
3
4
5
6
7
8// 声明一个数组
const tfboys = ['易烊千玺', '王源', '王俊凯'];
// 声明一个函数
function fn() {
console.log(arguments);
}
// 等价于 fn('易烊千玺', '王源', '王俊凯')
fn(...tfboys);-
输出
...
-
-
数组的合并
-
concat
concat
-
...
扩展运算合并数组 -
数组的克隆
( 浅拷贝
)1
2
3
4// 声明一个数组
const tfboys = ['易烊千玺', '王源', '王俊凯'];
const girlBoyfriends = [...tfboys];
console.log(girlBoyfriends); -
将一个伪数组转换为一个真正的数组
-
输出
伪数组转为真实数组
-
-
Symbol 基本使用
-
介绍
Es6
引入了一种新的原始数据类型 Symbol
,表示独一无二的值
,它是 Javascript
语言的第其中数据类型, 是一种类似于字符串的数据类型 -
特点
-
Symbol
的值是唯一的, 用来解决命名冲突的问题 -
Symbol
值不能与其他数据进行运算 (自己也不行) symbol
不能运算 -
Symbol
定义的对象属性不能使用 for in
循环遍历,但可以使用 Reflect.ownKeys
来获取对象的所有键名
-
-
函数式创建
1
2
3
4
5
6
7let s1 = Symbol();
console.log(s1, typeof s1);
let s2 = Symbol('内容是标识,和注释一样');
let s3 = Symbol('内容是标识,和注释一样');
// false
console.log(s2 === s3); -
Symbol.for
创建 1
2
3
4
5// 可以得出唯一的 Symbol
let s4 = Symbol.for('A')
let s5 = Symbol.for('A')
// true
console.log(s4===s5); -
数据类型总结
1
2
3
4
5
6USONB: you are so niubility
U undefined
S String symbol
o Object
n null number
b boolean -
Symbol
可以给对象安全的添加方法
迭代器
-
介绍
迭代器
( Iterator
)是一种接口, 为各种不同的数据结构提供统一的访问机制, 任何数据结构只要部署了 Iterator
接口, 就可以完成遍历操作 -
特性
-
Es6
创造了一种新的便利命令 for of
循环,Iterator
接口主要提供 for of
消费 -
原生具备
Iterator
接口的数据 ( 可以使用 for of
)遍历 Array
Arguemnts
Set
Map
String
TypedArray
NodeList
-
for of
遍历数组 1
2
3
4let arrayWorld = ['A', 'B', 'C'];
for (const word of arrayWorld) {
console.log(word);
} -
工作原理
-
创建一个指针对象,
指向当前数据结构的起始位置 创建一个指针对象, 指向当前数据结构的起始位置 -
第一次调用对象的
next()
方法, 指针会自动指向数据结构的第一个成员 next
方法调用 -
接下来不断调用
next
方法, 指针一直往后移动, 直到指向最后一个成员 连续调用 next
-
每调用
next
方法返回一个包含 value
和 node
属性的对象
-
-
生成器
-
就是一个特殊的函数
(异步) -
创建
1
2
3
4
5
6
7function* fn() {
console.log('Hello fn!');
}
let _fn = fn();
// 真正的调用
_fn.next(); -
yield
分割 1
2
3
4
5
6
7
8
9function* fn() {
console.log('Hello fn!');
yield 'H next'
yield 'H next next'
}
let _fn = fn();
// 真正的调用
_fn.next();-
输出
生成器 -
生成器的函数参数
参数传递 -
生成器函数实例
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// 1s
后输出 11 2s 后输出 22 3s 后输出 33
function one() {
setTimeout(() => {
console.log(1111);
iterator.next();
}, 1000);
}
function two() {
setTimeout(() => {
console.log(2222);
iterator.next();
}, 2000);
}
function three() {
setTimeout(() => {
console.log(3333);
}, 3000);
}
function* gen() {
yield one();
yield two();
yield three();
}
let iterator = gen();
iterator.next()
-
Promise
-
介绍
Promise
是 Es6
引入的异步编程的新解决方案, 与发生 Promise
是一个构造函数, 用来封装异步操作并可以获取其成功或失败的结果 Promise
构造函数: Promise(excutor){}
Promise.prototype.then
方法 Promise.prototype.catch
方法
Set
-
介绍
Es6
提供了新的数据结构 Set(集合)
,它类似于数组,但成员的值都是唯一的, 集合实现了 iterator
接口,所以可以使用 扩展运算符
和for of
进行遍历 -
集合的属性和方法
size
返回集合的元素个数 add
增加一个新元素, 返回当前集合 delete
删除元素,返回 boolean
值 has
检测集合中是否包含某个元素, 返回 boolean
值
-
输出
Size
-
实践
-
数组去重
1
2
3
4
5
6
7let arr = [1, 2, 4, 5, 1, 2, 3, 8, 9, 10, 1];
console.log('未去重之前数组长度: ', arr.length);
console.log(arr);
// 数组去重
let newArr = [...new Set(arr)];
console.log('通过Set 去重后, 数组长度: ', newArr.length);
console.log(newArr);-
输出
数组去重
-
-
交集
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24// 声明数组
let arr1 = [1, 2, 4, 5, 1, 2, 3, 8, 9, 10, 1];
// 声明数组
let arr2 = [4, 5, 1, 3, 2, 4, 1];
// 通过Set 将数组 1 去重并过滤
let result = [...new Set(arr1)].filter(item => {
// 将数组2 转换为 Set 去重
let s2 = new Set(arr2);
// 通过Set 方法判断元素是否存在
if (s2.has(item)) {
// 存在
return true;
} else {
// 不存在
return false;
}
});
console.log(result);
// 简化
let res = [...new Set(arr1)].filter(
item => new Set(arr2).has(item)
);
console.log(res);-
输出
交集
-
-
并集
1
2
3
4
5
6
7// 声明数组
let arr1 = [1, 2, 4, 5, 1, 2, 3, 8, 9, 10, 1];
// 声明数组
let arr2 = [4, 5, 1, 3, 2, 4, 1];
// 数组合并 => 转换为 Set去重 => 再转化为数组
let union = [new Set([...arr1, ...arr2])];
console.log(union); -
差集
1
2
3
4// S1 - S2(S1
中存在,S2 中不存在)
let res = [...new Set(arr1)].filter(
item => !(new Set(arr2).has(item))
);
-
Map
-
介绍
Es6
提供了 Map
数据结构, 它类似于对象, 也是键值对的集合, 但是 键
的范围不限于字符串,各种类型的值 (包括对象) 都可以当作键, Map
也实现了 iterator
接口,所以可以使用 扩展运算符
和for of
进行遍历 -
Map
的属性和方法 size
返回 Map
的元素个数 set
增加一个新元素, 返回当前 Map
get
返回键名对象的键值 has
检测 Map
中是否包含某个元素, 返回 boolean
值 clear
清空集合, 返回 undefined
-
基础使用
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// 声明 Map
let map = new Map();
// 添加
map.set('coderName', 'coder-itl');
map.set('coderAge', 18);
let coderInfo = {
address: 'BJ',
};
// 对象最为 key
map.set(coderInfo, ['SH', 'HN', 'SX']);
// value是一个函数
map.set('change', () => {
console.log('你有目标吗?');
});
// 获取 map元素个数
console.log(map.size);
// 获取元素怒
console.log(map.get('coderName'));
// 迭代器使用
for (const iterator of map) {
console.log(iterator);
}
// 删除
map.delete('coderInfo');
map.clear()
console.log(map);
Class -类
-
简介
Es6
提供了更接近传统语言的写法, 引入了 Class(类)
这个概念, 作为对象的模板,通过 class
关键字, 可以定义类, 基本上, Es6
的 class
可以看作只是一个语法糖, 它的绝大部分功能, Es5
都可以做到, 新的 class
写法只是让对象原型的写法更加清晰, 更像面向对象编程的语法而已 -
知识点
class
声明类 constructor
定义构造函数初始化 extends
继承父类 super
调用父级构造方法 static
定义静态方法和属性 - 父类方法可以重写
-
使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16// 声明类
class Phone {
// 定义一个有参的构造函数
constructor(brand, price) {
// 初始化
this.brand = brand;
this.price = price;
}
// 声明一个方法 必须使用 方法名(){ // ... 方法体 }
call() {
console.log('正在通话中,请稍后在拨....');
}
}
// 实例化
let phone = new Phone('IQ Neno5', 2999);
console.log(phone); -
静态成员
1
2
3
4
5
6
7
8
9
10
11
12// 声明类
class Phone {
// 静态属性 属于类 不属于实例对象
static name = '手机';
static change() {
console.log('我可以改变世界!');
}
}
// 实例化
let phone = new Phone();
console.log(phone.name); // undefined 不属于实例对象
console.log(Phone.name); // 属于类 -
类继承
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// 声明类
class Phone {
constructor(brand, price) {
this.brand = brand;
this.price = price;
}
// 父类的成员属性
call() {
console.log('正在通话中,请稍后再拨....');
}
}
class IQNeoo5 extends Phone {
constructor(brand, price, color, size) {
// 调用父级构造函数
super(brand, price);
// 初始化子级属性
this.color = color;
this.size = size;
}
// 子级特有成员属性
photo() {
console.log('我拍了一张照片!');
}
playGame() {
console.log('我正在进行xxx 游戏中....');
}
}
// 实例化
let phone = new IQNeoo5('IQNeno5', 1999, '红色', 6.54);
console.log(phone);
// 调用父级方法
phone.call() -
子类对父类方法的重写
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22// 父类有 call
// 子类重写
class IQNeoo5 extends Phone {
constructor(brand, price, color, size) {
// 调用父级构造函数
super(brand, price);
// 初始化子级属性
this.color = color;
this.size = size;
}
// 子级特有成员属性
photo() {
console.log('我拍了一张照片!');
}
playGame() {
console.log('我正在进行xxx 游戏中....');
}
// 重写 子类不能直接调用父类方法
call(){
console.log('完全重写了父类....');
}
} -
get
和 set
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16// 声明类
class Phone {
get price() {
console.log('price 属性被读取了');
return 'data';
}
// 需要传入一个参数
set price(val) {
console.log('price 被修改时将会被调用...');
}
}
// 实例化对象
let phone = new Phone();
// 读取属性
console.log(phone.price);
phone.price = 'free';