ES6总结整理

165 阅读10分钟

ES6总结整理

//以下大部分内容总结自B站up主光影哔哩上传的深入解读ES6系列(全18讲),播放量较多那个

1.

babel == browser.js

<script arc="browser.js" charset="-8"></script>
<script type=“text/babel”></script>

2.

JS中,关于var:可以重复声明;无法限制修改;没有块级作用域

ES6中,let:不能重复声明;变量值可修改;有块级作用域;不存在变量提升;有暂时性死区

ES6中,const:不能重复声明;变量值不可修改;有块级作用域;不存在变量提升

3.const对象冻结

正常一个const对象

const person = {};
person.name = “aaa”;//可以修改对象的属性
person.age = 26;
console.log(person.name);//aaa
console.log(person.age);//26
console.log(person);//Object {name:”aaa”, age:26}
person = {name:”bbb”};//报错//person为const对象,不能修改

const冻结

const person = Object.freeze({});
person.name = “aaa”;//冻结后再修改,修改不了
person.age = 26;
console.log(person.name);//undefined
console.log(person.age);//undefined
console.log(person);//Object

只能写成下面的形式

const person = Object.freeze({
	name:”aaa”;
	age:26;
});
console.log(person.name);//aaa
console.log(person.age);//26
console.log(person);//Object

//由于const对象内部可能也是对象,所以需要全面冻结

//全面冻结程序
var constantize = (obj) =>{
	Object.freeze(obj);
	Object.keys(obj).forEach(key,value) => {
		if(typeof obj[key] === ‘object’){
		constantize(obj[key]);
		}
	}
}; 

4.跨模块常量

用export和import

5.解构赋值

1.等号左右两边结构必须一样;

2.右边必须是个东西(见下面的第一个例子);

3.声明和赋值不能分开,必须在一句话中完成。

let [a,b,c] = [1,2,3];//数组
console.log(a,b,c);//1 2 3
let {a,c,d} = {a:12, c:5, d:6};//JSON
console.log(a,c,d);//12 5 6

对象结构赋值,指定默认值时,默认值生效的条件是,对象的属性值严格等于undefined,解构失败值为undefined

var {x = 3} = {x:undefined};
console.log(x);//3
var {y = 3} = {y :null};//不满足默认值生效条件
console.log(y);//null
 var x;
{x} = {x:1};//JS引擎将{x}理解为一个代码块,但是这个代码块没有声明
console.log(x);//报错

//需要加一个()

var x;
({x} = {x:1});
console.log(x);//1

现有的对象方法

console.log(Math.sin(Math.PI/6));//0.4999999999994
let {sin, cos, tan} = Math;
console.log(sin(Math.PI/6));//0.49999999999994

字符串的解构赋值

const [a, b, c, d, e] = “hello”;
console.log(a);//h//说明可以把字符串当作一个数组
console.log(b);//e
const {length:len} = “hello”;
console.log(len);//5//说明把字符串当作对象时,可以使用它的属性
const {length} = “hello”;
console.log(length);//5

函数参数的解构赋值

function sum([x,y]){
	return x + y;
}
console.log(sum([1,2]));//3

函数参数解构赋值的默认值

function fun({x = 0, y = 0} = {}){
	return [x, y];
}
console.log(fun({x:100, y:200}));//[100, 200]
console.log(fun({x:100}));//[100, 0]
console.log(fun({}));//[0, 0]
console.log(fun());//[0, 0]

函数参数解构赋值的默认值undefined

function fun({x, y } = {x:0, y:0}){//{x,y}仅仅是声明变量,它的值是多少取决于实参
	return [x, y];
}
console.log(fun({x:100, y:200}));//[100, 200]
console.log(fun({x:100}));//[100, undefined]
console.log(fun({}));//[undefined, undefined]
console.log(fun());//[0, 0]//默认没有在函数参数中做解构赋值,而是在对象中做解构赋值

解构赋值的用途:

交换变量的值;从函数返回多个值;函数参数的定义;提取json数据;函数参数的默认值;遍历Map结构;输入模块的指定方法

6.箭头函数

1.如果只有一个形参,()可以省略;

2.如果只有一个return语句,{}和return可以省略

7.函数的参数

1.参数扩展/数组展开

形参(a,b,...args)//args是一个数组形式,表示剩余参数(Rest Parameter),必须时最后一个形参,(a,b,...args,c)是错的

1.1收集剩余参数

function show(a,b,...args){}

1.2展开数组

let arr = [1,2,3];

...arr//代表了1,2,3。展开后的效果跟直接把数组内容写在这一样;

注:像下面的这种赋值方式不能用,其他方式都能用

let a;
let arr = [1,2,3];
a = ...arr;//这种赋值方式的用法是错的

2.默认参数

function show(a, b = 5, c = 12){......}

8.数组

map 映射:一个对一个;

reduce 汇总:一堆出来一个;

filter 过滤器

forEach 循环/迭代

map

let arr = [1,2,5,8];
let result = arr.map(function(item){
	//item是arr中的每一个值
	return item*2;
});
alert(result);

上面代码可以简写为:

let result = arr.map(item=>item*2);

reduce

let arr = [12,69,180,8763];
let result = arr.reduce(function(temp,item,index){
	//temp是中间结果,item是下一个参数,index是索引
	alert(temp + ‘,’ + item + ‘,’ + index)
});
//12,69,1//这也是index从1开始的原因
//undefined,180,2
//undefined,8763,3
let arr = [12,69,180,8763];
let result = arr.reduce(function(temp,item,index){
	return temp + item;
});
alert(result);//9024
//12 69 =>81
//81 180 =>261
//261 8763 =>9024

filter

let arr = [12,5,8,99];
//能被3整除的留下,通过true/false决定保留还是不保留
let result = arr.filter(item =>
	if(item % 3 ==0){
		return true;
	}else{
		return false;
	}
)
alert(result);//12,99
//上面的item % 3 ==0本身就是个布尔值,可以写为{return item % 3 ==0};
//整体改为let result = arr.filter(item => item % 3 ==0);

forEach

let arr = [12,5,8,9];
arr.forEach(item =>{alert(item)});//12,5,8,9
arr.forEach((item,index)=>{alert(index + ‘:’ +item)});

9.字符串

1.两个新方法

startsWith 以...开头

endsWith. 以...结尾

let str=“lixinS319070033.github.io”;
console.log(str.startsWith(’lixin’)); //true

2.字符串模板

直接把东西插到字符串里面,字符串用反单引号`包住,${东西}

可以折行

let a = 12;
let str = `a${a}bc`;
alert(str); //a12bc

折行

let title = ‘标题’;
let content = ‘内容’;
let str = `<div>
		   <h1>${title}</h1>
		   <p>${content}</p>
		   </div>`;

10.面向对象

1.构造器和类class分开

2.class里面直接加对象

class User{
	constructor(name,pass){
		this.name = name;
		this.pass = pass;
	}
	showName(){
		alert(this.name);
	}
	showClass(){
		alert(this.pass);
	}
}

继承

//代码使用上面的User类
class VipUser extends User{
	constructor(name,pass,level){
		//在执行父类的构造函数时,超类==父类
		super(name,pass);
		this.level = level;
	}
	showLevel(){
		alert(this.level);
	}
}
var v1 = new VipUser(’blue’, ’123456’, 3);
v1.showName();
v1.showPass();
v1.showLevel();

面向对象应用——React 里面强依赖于ES6

React:

1.模块化/组件化—class

2.强依赖于JSX==babe==browser.js

11.JSON

1.JSON对象

let json = {”a”:12, “b”:5};
let str = ‘abc’ + json; 
alert(str); //abc[object Object]

let str = ‘abc’ + JSON.stringify(json); //abc{“a”:12, “b”:5}

let str = ‘abc’ + encodeURIComponent(JSON.stringify(json)); //abc%....%....一堆编码
let str = ‘{”a”:12, “b”:5}’;
let json = JSON.parse(str); //{”a”:12, “b”:5}
json的标准写法:

1.只能用双引号,不能用单引号

2.所有的名字(key)都必须用引号包起来

2.简写

名字(key)和值(value)一样时,可以只写一个

例:json = {”a”:a, “b”:b, “c”:4};可简写为json = {a, b, “c”:4};

方法简写

let json = {
	”a”:12,
	show:function(){
		alert(this.a);
	}
}

简写为:

let json = {
	“a”:12,
	show(){
		alert(this.a);
	}
}

12.Promise

异步请求:操作之间无关系,同时进行多个操作,代码复杂

同步请求:同时只能做一件事,代码简单

promise清除异步操作,用同步一样的方式来书写异步代码

//使用Promise需要新创建一个Promise对象
let p1 = new Promise(function(resolve,reject){
	//异步代码
	//resolve-成功
	//reject-失败
	$ajax({
		url:’data/arr.txt’,
		dataType:’json’,
		success(arr){
			resolve(arr);
		},
		error(err){
			reject(err);
		}
	})
})
//使用对象来执行方法
p1.then(function(arr){
		//成功代码,对应resolve()
		alert(”成功了”);
	},function(){
		//失败代码,对应reject()
		alert(”失败了”);
})

上面代码和使用ajax差不多,但有多个ajax对象时,再重新创建个p2对象

let p2 = new Promise(function(resolve,reject){
	$ajax({
		url:’json.txt’,
		dataType:’json’,
		success(arr){
			resolve(arr);
		},
		error(err){
			reject(err);
		}
	})
})
//再使用p2.then(),那就真的和ajax差不多了,就没有意义了
//Promise有个all()方法
Promise.all([
	p1,p2
]).then.(function(arr){
//解构赋值
	let [res1, res2] = arr;
	alert(”全部都成功了”);
	alert(res1);
	alert(res2);
},function(){
	alert(”至少有一个失败了”);
})

//将p1,p2用一个函数表示

function createPromise(url){
	return new Promise(function(resolve,reject){
		$ajax({
			url:url,//名字和值一样,可以简写为url
			dataType:’json’,
			success(arr){
				resolve(arr);
			},error(err){
				reject(err);
			}
		})
	})
}
Promise.all([
	createPromise(’data/arr.txt’),
	createPromise(’json.txt’)
]).then.(function(arr){
	let [res1, res2] = arr;
	alert(”全部都成功了”);
	alert(res1);
	alert(res2);
},function(){
	alert(”至少有一个失败了”);
})

jQuery中有更方便的方法

//jQuery中的ajax返回值就是一个Promise对象

Promise.all([
	$.ajax({url:’data/arr.txt’, dataType:’json’}),
	$.ajax({url:’json.txt’}, dataType:’json’)
]).then.(function(results){
	let [arr, json] = results;
	alert(”全部都成功了”);
	alert(arr);
	alert(json);
},function(){
	alert(”至少有一个失败了”);
})

上面的代码大致可以简化为:

Promise.all([$.ajax({......}), $.ajax({......}), $.ajax({......})]).then(results=>{
	//对了时的代码
}, err =>{
	//错了时的代码
})

Promise.all()//全要成功,一个不能少

Promise.race()//竞速,哪个快用哪个

Promise.race([
	$.ajax({url:’........’, ......}),
	$.ajax({url:’......’, ......})
]);

13.generator生成器

是一个特殊一点的函数,generator函数不能写成箭头函数的形式

//普通函数—一路到底

function show(){
	alert(‘a’);
	alert(’b’);
}

//generator函数—中间能停,踹一脚走一步,例如请求数据等异步操作

//为什么可以走走停停的,因为在generator函数内部其实是生成了许多小函数,

//例如下面的例子可以拆成这两个函数

function show1(){
   alert(’a’);
}
function show2(){
   alert(’b’);
}

//第一次next(),运行show1(),第二次next(),运行show2()

//generator函数本质上就是这样,当然这个过程是看不到的

function *show(){//三种形式,function *show()或function * show()或function* show(),
	//但这种*两边都贴上的形式不可以,function*show()
	alert(’a’);
	yield;//放弃,暂时不往下执行
	alert(’b’);
}
//show()不会执行
//因为generator函数不会直接运行函数里面的代码,而是创建了一个generator对象出来
let genObj = show();
alert(genObj);//[object Generator]
genObj.next();//a弹出//遇到yield放弃执行下面代码
genObj.next();//b弹出

yield可传参可有返回值

传参

function *show(num1,num2){
	alert(`${num1}`, `${num2}`);//99,88
	alert(’a’);
	let a = yield;
	alert(’b’);
	alert(a);//5,原因看下图解析,将5直接传给了a
}
let genObj = show(99,88);//第一个过程传参和正常函数一样传参
genObj.next(12);//第一个next对于传参来说是废的,是没有办法给yield传参的
genObj.next(5);//next里的参数是传给yield的

1

返回

function *show(){
	alert(’a’);
	yield 12;
	alert(’b’);
}
let gen = show();
let res1 = gen.next();
console.log(res1);//{value:12, done:false}//done:false表示还没完成
let res2 = gen.next();
console.log(res2);//{value:undefined, done:true}
function *show(){
	alert(’a’);
	yield 12;
	alert(’b’);
	return 55;//最后的结果用return往外给
}
let gen = show();
let res1 = gen.next();
console.log(res1);//{value:12, done:false}//done:false表示还没完成
let res2 = gen.next();
console.log(res2);//{value:55, done:true}

2

3

异步操作

1.普通的回调函数,冗长

2.Promise,适合一次读一堆,这一堆没什么逻辑联系

3.generator,适合内容之间带有逻辑性的,其实generator就是Promise的一种封装

4....

另:generator—KOA(node.js里的东西)


ES7和ES8预览

1.数组—includes数组是否包含某个东西

let arr = [32, 5, 8];
alert(arr.include(99));//false

2.

数组—keys/values/entries,与for...of循环配合使用

JSON—keys/values/entries,暂时还不支持

keys—把数组里面的所有key拿出来 0,1,2,3,4,...

values—把数组里所有的value拿出来 12,4,5

entries—把数组里所有的键值对(key-value)拿出来,一个key和一个value叫entry实体,{key:0,value:12},{key:1,value:4},{key:2,value:5}

for...in 用于循环数组,循环JSON的

对于数组来说,循环下标(key)

对于JSON来说,循环key

for...of 用于循环迭代器(iterated)的

对于数组来说,循环值(value)

对于JSON来说,报错,JSON对象是一个不可迭代的对象,不是一个迭代器,没有iterator接口

let arr = [12,4,5];
let json = {”a”:12,”b”:5};
for(let i in arr){
	alert(i);//循环数组的下标0 1 2 
}
for(let i of arr){
	alert(i);//循环12 4 5
}
for(let i in json){
	alert(i);//循环a b 
}
for(let key in arr.keys()){
	alert(key);//循环数组的下标0 1 2 
}
for(let value of arr.values()){
	alert(value);//目前还不支持,可能将来会支持
}
for(let entry of arr.entries()){
	alert(entry);//循环0,12 1,4 2,5
}
for(let [key,value] of arr.entries()){
	alert(`${key}=${value}`);
	//循环0=12 1=4 2=5
	//也一定程度上解决了values()还不支持的问题
}

3.幂

Math.pow(3,8)//3的8次方

3**8//3的8次方

4.数组

padStart—向前面补东西

padEnd—向后面补东西

console.log(‘(’ + ’abc’.padStart(10) + ‘)’);//(    abc)
console.log(‘(’ + ’abc’.padStart(10,0) + ‘)’);//(0000000abc)
console.log(‘(’ + ’abc’.padEnd(10) + ‘)’);//(abc    )

5.语法容忍度

[12,6,8]//[12,6,8,]也是对的
alert([12,6,8,])//12,6,8

6.参数容忍度

function show(a,b,c,){...}//参数里有逗号也是对的

7.

用async await 取代generator yield,用法基本差不多

async await 优点:

1.不依赖于外部的runner了—统一并且性能也高了

2.可以使用箭头函数

async function show(){
	alert(’a’);
	await;
	alert(’b’);
}

//async await 和generator yield在代码实现上的书写的差别

//runner是别人写好的一个外部辅助的

4

//使用箭头函数的

5