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的
返回
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}
异步操作
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是别人写好的一个外部辅助的
//使用箭头函数的