前面也说过ES6新特性,现在再了一个ES6中的新特性–箭头函数。
其实箭头函数这个在使用的时候会让代码变得简单,但是其可读性个人觉得对于新手来说有些差,毕竟有些关键字被省略了,不多数现在来一个例子:
// 以前声明一个函数
var test1=function(){
console.log('test1');
}
test1();
// 现在来一个箭头函数
var test2=test3()=>{
console.log('test2');
}
test2();
这个就有一个问题为什么用表达式进行演示而不直接演示?
因为会报错。
test3()=>{
console.log('test3');
};
()=>{
console.log('test4');
};
test3会报错,后面写test4虽然不报错,但是有一个问题,如何调用?所以一般箭头函数是表达式声明函数,或者是作为某个方法中的回调函数,其实有点像是Java中的匿名函数了。
箭头函数语法
箭头函数因为其参数不同也会也会程序不同的样式:
最基本格式:
// 有参
(param1, param2, …, paramN) => { statements }
//如果是一个参数的话可以省略小括号
Param => { statements }
// 无参
() => { statements }
基本格式就不再具体演示了。
// 如果函数方法体中只有一个一条语句,其实花括号也可以不写。
() => 一行函数;
(param1, param2, …, paramN) => 一行函数;
Param => 一行函数;
演示:
var a=(A,B)=> console.log(A,B);
var b= C=> console.log(C);
var c= ()=> console.log('无参');
这个又有一个新特征了,还有一个问题,那就是如果带有返回数据。
// 如果带有返回数据的话如果单独省略花括号会报错
var b= C=> return C*C;// 这个地方会报错的。
// 那就带上花括号
var b= C=> {return C*C};
可见报错了,
但是如果只有一句的话,也是可以省略花括号的,不过如果省略花括号还需要将return也省略掉
var b= C=> C*C;
箭头函数在参数和箭头之间不能换行。简单的说就是=> 这两个必须在一行
箭头函数中的this
在箭头函数中的this是静止的,this始终指向函数声明时所在的作用域下的this。
还是老规矩代码演示:
var name='window下名字';
var obj={
name:'对象下的名字',
}
var a=function(){
console.log(this.name);
}
var b=()=>{
console.log(this.name);
}
首先常规调用方法:
a();
b();
如果这样看似乎我前面说的没有意义,就像是说屁话一样了,但是通过call将this指向的对象就行修改。如果想要聊了call等三个修改this的用法和区别可以看另一篇文章:地址
a();
b();
可以看出在箭头的this是无法进行重新定向的,在箭头中this只是指箭头方法所在作用域,比如这个箭头函数所在的是window域。
案例演示1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试文档</title>
<style>
div{
width: 200px;
height: 200px;
background-color: green;
}
</style>
</head>
<body>
<div id="test1"></div>
<hr>
<div id="test2"></div>
<hr>
<div id="test3"></div>
<script>
var ele1=document.getElementById('test1');
var ele2=document.getElementById('test2');
var ele3=document.getElementById('test3');
ele1.addEventListener('click',function () {
var _this=this;
// 这个时候window 调动的window 所有想要将this重新定义
setTimeout(function () {
_this.style.backgroundColor='red';
},10)
});
// 这个地方如果这样用箭头函数 this就不是代表div还是window
ele2.addEventListener('click',()=>{
console.log(this);
})
ele3.addEventListener('click',function () {
setTimeout(()=>{
this.style.backgroundColor='red'
},1)
})
</script>
</body>
</html>
案例演示2
var arr=[1,2,3,4,5,6];
arr.filter((i)=>{
if(i%2==0){
return true;
}else {
return false;
}
})
所以看出箭头函数适合与this无关的回调,定时器数组的方法回调等,但是箭头函数不太适合与this相关的回调。
这样说可能还有点绕再来一个例子:
var obj1={
name:"张三",
getName:function () {
return this.name;
}
}
obj1.getName();// 输出的张三
然后再来一个箭头:
var obj2={
name:"张三",
getName: () =>{
console.log(this);
return this.name;
}
}
这个可以看出在箭头函数中很多时候this的指向就是一个头疼。在花括号中的this竟然还是指向window。所以一般不会在箭头函数中使用this。
箭头函数无法作为构造函数
var obj1=function(name) {
this.name=name;
}
var obj2= name => {
this.name=name;
}
所以在官网的时候说到:箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。
箭头函数不能使用arguments获得变量
如果不知道arguments可以看下一下前面我的文章,所以本篇只是简单的演示以及使用而已。
var a=function(){
console.log(arguments);
};
var b=()=>{
console.log(arguments);
}
可以看一下调用:
补充–方法参数
其实对于函数的参数,前面也聊过,现在再进行一些简单的补充。
设置参数默认值
其实这个JavaScript不是唯一可以为形参设置默认值,毕竟再python中也是可以的,如下:
// 一般有默认值的的放在后面
var test1=function(a,b=2,c=10){
console.log(a,b,c);
};
var test2= (a,b=2,c=10)=>console.log(a,b,c);
只要传递参数可以看出直接回覆盖形参默认值。
形参的解构赋值
其实这个再前面聊es6特性的解构中说,但是再聊一遍。
var obj={
name:"张三",
age:18
}
var test1=function ({name,age}) {
console.log(name,age);
}
var test2= ({name,age})=> console.log(name,age);
引入rest参数 用来代替arguments
ES6引起了rest参数,用户获取函数的实参,用来代替arguemnts,而这个其实如果了解Java的话看到下面的例子就会说不就是不确定参数吗?
老规矩演示:
var test1 =function(...args){
console.log(args);
}
var test2 =(...args)=>console.log(args);
aiguments得到的是一个伪数组,如果对伪数组不太了解的可以看前面文章:地址
而这个rest参数得到就是一个数组。
当然前面也可以放单个形参,而rest参数一般都放在最后。(默认参数也是默认放后面?到底谁再后面?当然是rest参数再后面了,不然后面的就不会生效)不然会报错。
补充扩展符1 ---- 调用方法作为参数中使用
在形参中可以叫做rest参数,但是在实参位置呢?又被叫做扩展符
符号:...
扩展运算符能将数组转换为逗号分隔二点参数序列。
演示:
var arr=['A','B','C'];
function test(){
console.log(arguments);
}
// 这个参数必须是可迭代,比如创建的对象本身不可迭代就不能如下用不然会报错
test(... aiguozhe)
可以产出在传递的时候,实参通过扩展符将其变成了三个参数进行传递。
补充扩展符2 ---- 合并数据
还可以来一个神奇的操作
var arr1=['A','B','C'];
var arr2=['D','F'];
将两个数组连接成一个数组可以如下操作:
aiguozhe=arr1.concat(arr2)
//或者
aiguozhe=[...arr1,...arr2]
结果:
补充扩展符3 ---- 对象的浅拷贝
还有就是在数组中使用,这个其实算是一种浅拷贝,如果想要了解想要了解深浅拷贝可以看文章:传送阵
下面开始演示:
var obj={
name:'李四',
test_obj:{
des:'测试'
}
}
var obj1={...obj};
obj.name='张三';
obj.test_obj.des='修改了';
补充扩展符4 ---- 字符串转数组
var test='string';
var arr=[...test];