变量
- let 不能重复声明;变量-可以修改;块级作用域;不存在变量提升
- const 不能重复声明;常量-不能修改;块级作用域;对于数组和对象的元素修改,不算做对常量的修改,不会报错
函数 - 箭头函数
1
2
3
4
5function(){} ----> ()=>{}
// 如果只有一个参数,()可以省略
// 如果只有一个return,{}可以省略
function(a){return(a*2)} ----> a => a*2this
是静态的,this始终指向函数声明时所在作用域下的this的值- 不能作为构造函数实例化对象
- 不能使用
arguments
变量
函数 - 参数
- 参数扩展
1
2
3
4
5
6
7
8
9
10//收集参数
function show(a, b, ...c){} //...c必须是最后一个
show(1,2,3,4,5);
a //1
b //2
c //[3,4,5]
...c // 3 4 5
//展开参数
//展开后的效果,跟直接把数组内容写在这一样 - 默认参数
1
function(a, b=1, c=2){}
rest
ES6引入rest
参数,用于获取函数的实参,用来代替arguments
- 参数扩展
解构赋值
- 左右两边结构必须一样
- 右边必须是个东西
- 声明和赋值不能分开(必须在一句话里完成)
1
2
3
4
5
6
7
8
9
10
11
12
13let [a, b, c] = [1, 2, 3];
console.log(a, b, c); //1 2 3
// --------------------------------------
function breakfast(){
return {dessert: 1, drink: 2, fruit: 3};
}
let {dessert: dessert, drink: drink, fruit: fruit} = breakfast();
console.log(dessert, drink, fruit); // 1 2 3
数组
map 映射
1
2
3
4
5
6
7
8let arr = [12, 5, 8];
let result = arr.map(function(item){ //let result = arr.map(item => item);
return item;
});
let score = arr.map(item => item>10?'大于10':'不大于10');
console.log(result); //[12, 5, 8]
console.log(score); //['大于10', '不大于10', '不大于10']reduce 汇总 一堆出来一个
1
2
3
4
5
6
7
8
9
10
11
12
13
14let arr = [10, 11, 12, 13];
let sum = arr.reduce(function(tmp, item, index){ //求和
return tmp + item;
});
let average = arr.reduce(function(tmp, item, index){ //求平均数
if(index != arr.length-1){
return tmp + item;
}else{
return (tmp + item) / arr.length;
}
});
console.log(sum); //46 求和
console.log(average); //11.5 求平均数fill 填充数组
参数:填充的内容, 起始位置, 结束位置1
2
3
4
5
6
7
8
9
10
11
12
13
14let result = arr.fill(6);
console.log(result); //[6, 6, 6, 6, 6]
//-----------------------
let arr = [1, 2, 3, 4, 5];
let result = arr.fill(6, 2);
console.log(result); //[1, 2, 6, 6, 6]
//------------------------
let arr = [1, 2, 3, 4, 5];
let result = arr.fill(6, 2, 3);
console.log(result); //[1, 2, 6, 4, 5]filter 过滤器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let result = arr.filter(item => {
if(item % 2 == 0){
return true;
}
});
console.log(result); //[2, 4, 6, 8]
//--------------- 简写
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let result = arr.filter(item => item % 2 == 0);
console.log(result); //[2, 4, 6, 8]Array.from()
将类数组对象转为真正的数组1
2let str = '123456';
console.log(Array.from(str)); // ['1', '2', '3', '4', '5', '6']Array.of()
将一组参数转换为数组1
console.log(Array.of(1, 2, 3, 4, 5, 6)); // ['1', '2', '3', '4', '5', '6']
find 找出第一个符合条件的数组元素
参数:
· 回调函数
· 回调函数内this指向遍历整个数组,遍历过程中调用回函数,如果回调函数的返回值为true,则返回当前在遍历的元素。
如果所有元素都不符合条件则返回 undefined1
2
3
4
5let arr = [1, 2, 3, 4, 5, 6];
let num = arr.find(function(value, index){
return value > 4;
});
console.log(num); //5findIndex 找出第一个符合条件的数组元素的索引
参数:
· 回调函数
· 回调函数内this指向遍历整个数组,遍历过程中调用回函数,如果回调函数的返回值为true,则返回当前在遍历的元素位置。
如果所有元素都不符合条件则返回 -11
2
3
4
5let arr = [1, 2, 3, 4, 5, 6];
let num = arr.findIndex(function(value, index){
return value > 4;
});
console.log(num); //4for of 遍历拥有遍历接口对象的属性值
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
41
42
43
44
45
46
47
48
49
50
51
52let arr = [1, 2, 3, 4, 5, 6];
for(value of arr){
consolelog(value);
}
//1
//2
//3
//4
//5
//6
//----------------------------
//遍历数组键名
let arr = [1, 2, 3, 4, 5, 6];
for(let key of arr.keys()){
console.log(key);
}
//0
//1
//2
//3
//4
//5
//----------------------------
//遍历数组键值
let arr = [1, 2, 3, 4, 5, 6];
for(let value of arr.values()){
console.log(value);
}
//1
//2
//3
//4
//5
//6
//----------------------------
//遍历数组键值对
let arr = [1, 2, 3, 4, 5, 6];
for(let [key, value] of arr.entries()){
console.log(key, value);
}
//0 1
//1 2
//2 3
//3 4
//4 5
//5 6for Each 循环(迭代)
字符串
- 多了几个新方法
1
2
3
4
5
6
7
8
9
10
11//includes
let str = 'abcdefg';
console.log(str.includes('a')); //true
//startsWith
let str = 'abcdefg';
console.log(str.startsWith('a')); //true
//endsWidth
let str = '1.text';
console.log(str.endsWith('text')); //true - 字符串模板 字符串连接
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17//直接串塞到字符串里边
//可以折行
let str1 = 'abcdefg';
let str2 = `12345${str1}6789`;
console.log(str2); //12345abcdefg6789
//--------------------
//可以添加标签
let str1 = 'abcdefg';
let str2 = `123456789`;
let breakfast = mark`数字:${str1},字符串:${str2}`;
function mark(string, ...values){
console.log(string); // ["数字:", ",字符串:", "", raw: Array(3)], raw: (3) ["数字:", ",字符串:", ""]
console.log(values); // ["abcdefg", "123456789"]
}
- 多了几个新方法
数值
- 二进制和八进制表示法
ES6提供了人二进制和八进制数值的新的写法,分别用前缀0b
和0o
表示。1
2
3
4let num1 = 0b11; //3 二进制
let num2 = 0o11; //9 八进制
let num3 = 100; //100 十进制
let num4 = 0xff; //255 十六进制 - Math对象的扩展
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16//Math.trun 去除小数部分,返回整数部分
let num = 1.23456;
console.log(Math.trunc(num)); //1
//Math.sign 判断一个数字是正数、负数还是零
let num1 = 10;
let num2 = -10;
let num3 = 0;
let num4 = -0;
console.log(Math.sign(num1)); //1
console.log(Math.sign(num2)); //-1
console.log(Math.sign(num3)); //0
console.log(Math.sign(num4)); //-0
//Math.hypot 返回所有参数的平方和的平方根(勾股定理)
console.log(Math.hypot(3, 4)); //5 Number.EPSILON
是JavaScript表示的最小精度
EPSILON 属性的值接近于 2.2204460492503130808472633361816E-161
2
3
4
5
6
7
8
9
10function equal(a, b){
if(Math.abs(a-b) < Number.EPSILON){
return true;
}else{
return false;
}
}
console.log(0.1 + 0.2 === 0.3); //false
console.log(equal(0.1+0.2, 0.3)); //trueNumber.isFinite
检测一个数值是否为有限数1
2
3console.log(Number.isFinite(100)); //true
console.log(Number.isFinite(100/0)); //false
console.log(Number.isFinite(Infinity)); //falseNumber.isNaN
检测一个数值是否为NaN1
console.log(Number.isNaN(123)); //false
Number.parseInt
Number.parseFloat
字符串转整数1
2console.log(Number.parseInt('123wq')); //123
console.log(Number.parseFloat('13.44'));//13.44
- 二进制和八进制表示法
对象表达式
1
2
3
4
5
6
7
8
9
10
11
12
13let dessert = 1;
let deink = 2;
let food = {
dessert: dessert,
deink: deink,
breakfast: function(){}
}
// -----------------------
let food = {
dessert,
deink,
breakfast(){}
}对象属性名
1
2
3
4
5
6let food = {};
let drink = 'hot drink';
food.dessert = 1;
food['hot dog'] = 2;
food[drink] = 3;对比两个值是否相等
Object.is()
1
2console.log(Object.is(NaN, NaN)); //true
console.log(Object.is(+0, -0)); //false把对象的值复制到另一个对象里
Object.assign()
1
2
3
4
5
6
7
8let breakfast = {};
Object.assign(
breakfast,
{drink: 1}
)
console.log(breakfast); //{drink: 1}设置对象的 prototype
Object.setPrototypeOf()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17let breakfast = {
getDrink(){
return 1;
}
}
let dinner = {
getDrink(){
return 2;
}
}
let sunday = Object.create(breakfast);
console.log(sunday.getDrink()); // 1
console.log(Object.getPrototypeOf(sunday) === breakfast); //true
Object.setPrototypeOf(sunday, dinner);
console.log(sunday.getDrink()); // 2
console.log(Object.getPrototypeOf(sunday) === dinner); //true__proto__
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20let breakfast = {
getDrink(){
return 1;
}
}
let dinner = {
getDrink(){
return 2;
}
}
let sunday = {
__proto__: breakfast
}
console.log(sunday.getDrink()); // 1
console.log(Object.getPrototypeOf(sunday) === breakfast); // true
sunday.__proto__ = dinner;
console.log(sunday.getDrink()); // 2
console.log(Object.getPrototypeOf(sunday) === dinner); // truesuper
1
2
3
4
5
6
7
8
9
10
11
12
13let breakfast = {
getDrink(){
return 1;
}
}
let sunday = {
__proto__: breakfast,
getDrink(){
return super.getDrink();
}
}
console.log(sunday.getDrink()); // 1迭代器 Iterators
迭代器
Iterator
是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator
接口,就可以完成遍历操作。- ES6创造了一种新的遍历命令
for...of
循环,Iterator
接口主要提供for...of
消费 - 原生具备
Iterator
接口的数据(可用for...of
遍历)
· Array
· Arguments
· Set
· Map
· String
· TypeArray
· NodeList - 工作原理
· 创建一个指针对象,指向当前数据结构的起始位置
· 第一次调用对象的next
方法,指针自动指向数据结构的第一个成员
· 接下来不断调用next
方法,指针一直往后移动,直到指向最后一个成员
· 每调用next
方法返回一个包含value
和done
属性对象注:需要自定义遍历数据的时候,需要想到迭代器。
- ES6创造了一种新的遍历命令
generator 生成器
生成器函数是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不同
面向对象
- class关键字、构造器和分类分开了
- class里面直接加方法
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
36class User{
constructor(name, pass){
this.name = name;
this.pass = pass;
}
showName(){
console.log(this.name);
}
showPass(){
console.log(this.pass);
}
}
let u1 = new User('名字', '密码');
u1.showName(); //名字
u1.showPass(); //密码
//---------------- 继承
class vipUser extends User{
constructor(name, pass, level){
super(name, pass);
this.level = level;
}
showLevel(){
console.log(this.level);
}
}
let v1 = new vipUser('名字', '密码', '等级');
v1.showLevel(); //等级
JSON
- JSON标准写法
- 只能用双引号
- 所有的名字(key)都必须用引号抱起来
- JSON对象
1
2JSON.stringify //转字符串
JSON.parse //转JSON - 简写
- 名字跟值(key跟value)一样,留一个就行
- 方法
show:function(){}
show(){}
- JSON标准写法
Symbol
ES6引入了一种新的原始数据类型
Symbol
,表示独一无二的值,它是JavaScript语言的第七种数据类型,是一种类似于字符串的数据类型。特点:
1)Symbol的值是唯一的,用来解决命名重瞳的问题
2)Symbol值不能与其他数据进行计算
3)Symbol定义的对象属性不能用for...in
循环遍历,但是可以使用Reflect.ownKeys
来获取对象的所有键名1
2
3
4
5
6
7
8
9
10
11//创建Symbol
let s = Symbol();
console.log(s, typeof s); //Symbol() symbol
let s2 = Symbol('张三');
let s3 = Symbol('张三');
console.log(s2, s3, s2===s3); //Symbol(张三) Symbol(张三) false
let s4 = Symbol.for('李四');
let s5 = Symbol.for('李四');
console.log(s4, s5, s4===s5); //Symbol(李四) Symbol(李四) truePromise
Promise是ES6引入的异步编程的新解决方案,语法上Promise是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。
· Promise构造函数:promise(excutor){}
· Promise.prototype.then方法
· setPromise.prototype.catch方法Set
ES6提供了新的数据结构Set(集合)。它类似于数组,但成员的值是唯一的,集合实现了iterator接口,所以可以使用 扩展运算符 和 for…of 进行遍历
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55//声明一个set
let s1 = new Set();
let s2 = new Set([1, 2, 3, 4, 3]);
console.log(s1, typeof s1); //Set(0) object
console.log(s2); //Set(4) {1, 2, 3, 4}
//size 返回集合的元素个数
console.log(s2.size); //4
//add 添加新元素,返回当前集合
s2.add(9);
console.log(s2); //Set(5) {1, 2, 3, 4, 9}
//delete 删除元素,返回 boolean 值
s2.delete(1);
console.log(s2); //true
//检测,是否包含
s2.has(1);
console.log(s2); //true
//清空
s2.clear()
console.log(s2); //Set(0)
//遍历
for(v of s2){
console.log(v);
}
//1
//2
//3
//4
//实例
let arr = [1, 2, 3, 4, 5, 6, 1, 2, 3];
//数组去重
let result = [...new Set(arr)];
console.log(result); //[1, 2, 3, 4, 5, 6]
//交集
let arr2 = [4, 5, 6, 4, 5, 6, 7];
let result = [...new Set(arr)].filter(item => new Set(arr2).has(item));
console.log(result); //[4, 5, 6]
//并集
let result = [...new Set([...arr, ...arr2])];
console.log(result); //[1, 2, 3, 4, 5, 6, 7]
//差集
let result = [...new Set(arr)].filter(itme => !(new Set(arr2).has(itme)));
let result2 = [...new Set(arr2)].filter(itme => !(new Set(arr).has(itme)));
console.log(result); //[1, 2, 3]
console.log(result2); //[7]Map
E6S提供了Map数据结构。它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map也实现了 iteretor 接口。所以可以使用 扩展运算符 和 for…of 进行遍历。
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//声明Map
let m = new Map();
//set 增加一个新元素,返回当前Map
m.set('name', '张三'); //Map(1) {name => 张三}
m.set('fn', function(){}); //Map(1) {fn => ƒ (){}}
let key = {
sex: '性别'
};
m.set(key, ['男', '女', '未知']); //Map(1) {{sex: '性别'} => (3) ['男', '女', …]}
//size 返回Map的元素个数
consle.log(m.size); //3
//删除
m.delete('name'); //Map(2) {fn => ƒ (){}, {sex: '性别'} => (3) ['男', '女', …]}
//获取 get 返回键名对象的键值
m.get('fn');
m.get(key);
//clear 清空集合,返回 undefined
m.clear();
//遍历
for(i of m){}
//has 检测 Map 中是否包含某个元素,返回boolean值
m.has('name');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
17
18
19
20
21
22
23
24
25
26
27
28
29
30class Phone{
//构造方法 名字constructor不能修改
constructor(brand, price){
this.brand = brand;
this.price = price;
}
//方法必须使用改语法,不能使用ES5的对象完整形式
call(){
console.log('我可以打电话');
}
}
let huaWei = new Phone('HuaWei', 4999);
huaWei.call(); //我可以打电话
console.log(huaWei); //Phone {brand: 'HuaWei', price: 4999}
//继承
class SmartPhone extends Phone{
constructor(brand, price, color, size){
super(brand, price);
this.color = color;
this.size = size;
}
//重写方法
call(){
console.log('我可以打视频电话');
}
}模块化
模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来。
好处:
· 防止命名冲突
· 代码复用
· 高维护性ES6之前的模块化规范
· CommomJS => NodeJS、Browserify
· AMD => requireJS
· CMD => seaJSES6模块化语法
模块功能主要有两个命令组成:export 和 import
· export 命令用于规定模块的对外接口
· import 命令用于输入其他模块提供的功能