ES6个人总结
一.模板字符串
基本用法和好处
比如声明一个变量,以前是用单引号或者用双引号来把字符串包起来
这两种方式
var name ="小明"
var sex = '男'
现在可以用模板字符串(反引号) ``
这样
var name= `小明`
好处是不再需要用+号来拼接字符串
例如
之前拼接的做法
var name ='小明'
console.log('我是'+name+',而且很帅')
现在使用模板字符串
var name =-'小明'
console.log(`我叫${name},而且很帅`)
当然,少量的代码是看不出方便之处的,当你在做一个很长的字符串拼接的时候就会感觉到,用模板字符串就很快的拼接完了.
二.解构赋值
1.对象解构
var obj={name:"张三",age:18}
var {name,age}=obj;
下面的对象里面生成2个变量,name值来自于obj.name、age值来自于obj.age
2.数组解构
因为数组是有顺序的一组数据.所以,要一 一对应起来,如果没有就返回undefined
var [name, age, sex] = ['小明', 14, '男']
数组也可以嵌套比如
var [cat, [name, age], sex] = ['小猫', ['旺财', 2], '女']
var [name, age, sex] = ['小明', 14,]
这里输出sex的时候返回的是undefined
注意:数组的元素是有顺序的,变量的取值由数组中元素的位置决定;而对象的属性没有序,但是变量必须与属性同名,才能取到正确的值。
3.函数的参数解构
声明一个fn函数,函数的参数是一个对象,把它传进去
function fn(obj){
console.log(obj.age); //5
console.log(obj.height) //180
}
fn({age:5,height:180})
//等价于
function fn({ age,height }){
console.log(age); //5
console.log(height) //180
}
fn({age:5,height:180})
三.函数rest参数
在es6中,函数给我们提供了一个参数,跟arguments参数差不多
但是arguments是伪数组,而rest是真数组,这个rest参数我们用(…args)来表示
例如
function fn (...args){
console.log(...args) //[1,2,3,4,5]
}
fn(1,2,3,4,5)
这样就可以直接使用数组里面的方法.
四.箭头函数
1.基本用法
普通匿名函数例如
div.onclick =function(){
console.log('这是普通匿名函数')
}
箭头函数的写法
div.onclick =()=>{
console.log('这是箭头函数')
}
有一个参数的写法
div.onclick =(n)=>{
console.log('这是箭头函数')
}
也可以这样写 是等价的
div.onclick =n=>{
console.log('这是箭头函数')
}
有2个及更多参数的箭头函数
var fn=(a,b,c)=>{
console.log("这是箭头函数")
}
2.与普通匿名函数的区别
1,箭头函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
也就是说
用箭头函数
div.onclick =()=>{
console.log(this) //window
}
不用箭头函数
div.onclick =function (){
console.log(this) //指向的是当前调用它的对象
}
2,不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
3,不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
应用场景
按钮组件点击,有各自不同而操作
首先不用箭头函数
为了方便观察把代码放在一起,现在我需要点击按钮,一秒后禁用.
<button>提交1</button>
<button>提交2</button>
<button>提交3</button>
<button>提交4</button>
<button>提交5</button>
<button>提交6</button>
var btn = document.querySelectorAll('button')
for (let i = 0; i < btn.length; i++) {
btn[i].onclick = function() {
var that=this;
setTimeout(function() {
that.disabled = true;
}, 1000);
}
}
因为定时器里面的回调函数是指向window的所以,要在定时器的外面,声明一个变量that,把当前的作用域存在that里面,然后在定时器里面使用,这样才行
用箭头函数
for (let i = 0; i < btn.length; i++) {
btn[i].onclick = function() {
因为箭头函数里面的没有自己的this 都是指向定义时的所在的作用域
setTimeout(() => {
console.log(this); //指向当前调用它的那个对象
this.disabled = true;
}, 3000);
}
}
这时就不需要保存作用域了,是不是方便了许多
当然,还有很多应用场景的,我这里只是举个例子而已.
五.Promise
1.基本用法
把异步操作封装在一个promise对象中
function fn(){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
console.log('执行操作')
这里是为了告诉外界这一步操作已经完成,可以继续执行下一步
resolve();
},1000);
})
}
调用fn
fn().then(()=>{
这里执行开始下一步
console.log('下一步操作')
})
promise中有两个参数,resolve和reject
这两个参数的含义是
执行了resolve()表示异步操作是成功的
执行了reject()表示异步操作是失败的
2.传参
function fn(){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
console.log('执行操作')
resolve('执行完成');
},1000);
})
}
res就表示上一个异步操作返回的参数值,可以是返回值,也可以是字符串
如果用异步操作来请求服务器数据,这里的res就表示从服务器中我获取到的数据
fn().then((res)=>{
这里执行开始下一步
console.log(res) //执行完成
console.log('下一步操作')
})
3.错误处理
捕捉错误可以用catch来捕捉异步回调中发生的错误
function f1(name){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
if(name=="abc"){
resolve("成功了");
}else{
reject("失败了")
}
},1000)
})
}
f1('abc').then((res)=>{
console.log(res) //成功了
var a=3;
a() //这里发生了错误,因为a不是函数
用catch可以捕获到回调中发生的错误
}).catch(res={
console.log(res) //a is not a function
})
4.作用
promise可以解决回调地狱的问题,
回调地狱就是不停的回调,
就像if条件判断,很多个条件判断语句,这样不但会变成回调地狱,代码看起来也很不顺眼
if(){
if(){
if(){
if(){}
}
}
}
或者ajax请求路径下面文件的数据,
$.get("/a",function(res){
$.get("/a/b",function(){
$.get("/a/b/c",function(){
$.get("/a/b/c/d",function(){
//...
})
})
})
})
又或者在node开发:开个服务器、接收一个请求、请求路径、访问数据库,读取文件;
这些都是异步操作,容易形成回调地狱
所以我们就需要promise来解决这个问题
function fn1(){
return new Promise(resolve=>{
setTimeout(()=>{
console.log('第一步');
异步逻辑已经执行完,必须要告诉外界我执行完了
resolve('第一步执行完成');
},1000)
})
}
function fn2(){
return new Promise(resolve=>{
setTimeout((res)=>{
console.log('第二步');
//告诉外界我执行完了
resolve('第二步执行完成');
},1000)
})
}
fn1().then(res=>{
console.log(res)
//返回一个promise对象
return fn2();
}).then(res=>{
console.log(res)
return fn1();
}).then(res=>{
console.log(res)
return fn2();
}).then(res=>{
console.log(res)
setTimeout(()=>{
console.log('完成');
},1000)
})
输出的顺序是 第一步-第一步完成----第二步-第二步完成----第一步-第一步完成----第二步-第二步完成----完成
六.async(其实是Promise的语法糖)
await可以执行异步操作,但是await必须在async函数内执行
1.用法
先封装好一个promise
function f1(){
return new Promise(resolve=>{
setTimeout(()=>{
console.log('执行操作');
告知外界执行结束
resolve('over');
},1000);
})
}
(async function(){
await f1(); 表示这是异步操作,下面的代码会在执行完这个异步操作后才执行
说白了,就是执行了resolve()
console.log('第二步');
await f1();
await f1();
console.log('第三步');
})()
await操作可以有返回值,这个返回值表示promise操作成功的返回值,
如果需要用到返回值,可以声明一个变量去接受,然后在使用这个返回值
就像这样 var a = await f1( ) 这时候就可以使用await的返回值了.
2.错误处理
如果await里面执行的异步操作发生了reject,或者发生了错误,那么只能使用try…catch语法来进行错误处理
比如
function f1(){
return new Promise((resolve,rejeck)=>{
setTimeout(()=>{
console.log('执行操作')
rejeck('出错了');
},1000);
})
}
(async function(){
try{
用a来接受rejeck返回的结果
var a = await f1()
console.log(a) //出错了
}catch(e){
console.log(e)
}
})()
在实际开发过程中一般用异步操作都是成功的,拿到返回值然后再进行下一步操作,因为不可能失败了还继续让程序运行下去的.
七.class 类
1.用法
定义一个类
class father (){
constructor(name) {
this.name=name;
}
}
var f1= new father('小明')
其实这个就相当与构造函数,只不过换了一种写法
function father (name){
this.name=name;
}
如果我们需要添加实例方法
class father (){
constructor(name) {
this.name=name;
}
定义方法
say(){
console.log(`我会说话,我的名字叫${this.name}`)
}
2.添加静态方法
添加静态方法
class father (){
constructor(name) {
this.name=name;
}
static say(){
console.log(`我会说话,我的名字叫${this.name}`)
}
访问静态方法
father.say()
这个say方法就是一个静态方法
- 静态成员:静态属性、静态方法
- 静态属性:通过类本身来访问:father.name
- 静态方法:通过类本身来访问的一个方法:father.say()
3.类的继承(extends)
在es6中有extends,所以让我们的继承就方便了很多
先创建一个父类
class Father(){
constructor (name,age){
this.name=name
this.age=age
}
}
子类继承父类 这里面 须调用父类构造方法,如果不调用就会报错
class Sun extends Father {
constructor(name, sex) {
super(name);
调用父类构造方法,从而给子类的实例添加了name属性
this.sex = sex;
}
}
var sun =new Sun('小明','男')
console.log (sun) //sun:{name:'小明',sex:'男'}
这里的name属性是继承了父类里面的name属性
super关键字的作用
super关键字是在子类对象内部指代其父类对象的引用
八.对象扩展运算符(…)
var obj1= {name:'小明',age:13}
var obj2={...obj1}
console.log(obj2) // {name:'小明',age:13}
也可以添加其他属性和修改拷贝过来的属性
var obj1= {name:'小明',age:13}
var obj2={...obj1}
var obj3 = {...obj1,age:11,sex:'男'}
console.log(obj2) // {name:'小明',age:13}
console.log(obj3) // {name:'小明',age:11,sex:''男'}
console.log(obj1) // {name:'小明',age:13}
方便很多,以前要实现拷贝还要遍历然后在把数组或者对象添加进来才能实现拷贝继承,现在用对象扩展运算符很快就拷贝好了.
作用
实现拷贝继承,当然了只是浅拷贝而已,实现深拷贝的话就要(浅拷贝+递归),当然也有其他方法实现深拷贝(这里就不说这么多)