本文深入解析ES6箭头函数的语法特性,涵盖完整写法与多种简写规则,包括省略参数括号、函数体大括号及return语句的条件。重点探讨箭头函数中this的静态绑定机制,通过对比普通函数与箭头函数在回调、网络请求封装等场景下的表现,阐明其解决this指向问题的优势,并结合map、filter、reduce等数组方法提供实战代码示例。
箭头函数
ES6标准引入了箭头函数这一简写形式,它不仅大幅减少了代码量,使代码结构更为简洁优雅,还有效解决了传统函数中this指向复杂的问题。下文将详细解析箭头函数的使用技巧与核心机制。
语法规则
1. 传统函数定义方式
function foo1(){}
var foo2 = function(name,age){
console.log("函数体代码",this,arguments);
console.log(name,age);
}
2. 箭头函数的完整标准写法
var foo3 = (name,age) => {
console.log("箭头函数的函数体")
console.log(name,age);
}
3. 利用箭头函数遍历数组
传统的遍历写法示例
var names = ["abc","cba","nba"];
names.forEach(function(item)){
console.log(item);
})
使用箭头函数进行数组遍历的写法
names.forEach((item,idx,arr)=>{
console.log(item,idx,arr);
}
)
setTimeout(()=>{
console.log("setTimeout");
},3000)
简写规则
1. 当箭头函数仅包含一个参数时,参数外部的括号可以省略。
name.forEach(item =>{
console.log(item);
}
结合filter()方法与箭头函数,可以高效地筛选出符合特定条件的数组元素。
var newNums = nus.filter(item =>{
return item % 2;
})
3. 若函数体仅包含一条执行语句,则可省略函数体的大括号{}。
此时,该语句的执行结果将自动作为函数的返回值,因此无需显式使用return关键字。
names.forEach(item => console.log(item));
在filter()函数仅有一行逻辑时,可直接省略大括号{}以简化代码。
varans = worker.filter( item=>item % 2 )
4. 若箭头函数的默认返回值是一个对象,必须为该对象添加圆括号()。
注意:这一规则在React的Redux开发中经常被用到。
当箭头函数同时涉及执行体的大括号和对象的大括号时,JavaScript引擎可能无法正确区分二者。
var arrFn = () =>{} //此大括号是执行体
var arrFn = () =>{ name : "why"}// 此大括号是对象
因此,为了明确区分执行逻辑与返回对象,必须给返回的对象加上圆括号()。
var arrFn = () =>({ name : "why"})
常见应用场景
map
map() 方法定义在JavaScript的Array原型中,它返回一个新数组,新数组中的元素是原始数组每个元素调用回调函数后处理得到的值。
需要特别注意以下几点:
- map()函数不会对空数组执行回调函数。
- map()函数不会修改原始数组,而是生成并返回一个新数组。
- array.map(function(currentValue, index, arr), thisValue)
参数详细说明:
1. function(currentValue,index,arr):必填参数
- 数组中的每个元素都会执行该回调函数。
- currentValue:必填,表示当前正在处理的元素值。
- index:可选,表示当前元素的索引,即第几个数组元素。
- arr:可选,表示当前元素所属的原始数组对象。
2. thisValue:可选,当执行回调函数时,作为“this”值传递给函数的对象。
例1:将原数组中的每个元素平方后,赋值给新数组。
let arry = [1,2,3,4];
let newArray = array.map((item)=>{
return item*item;
})上述逻辑也可以简化为一行代码实现。
let newArray = array.map(item =>item * item)
例2:筛选出原数组中的偶数,将其平方后赋值给新数组。
filter
filter() 方法用于对数组进行过滤操作。
- 其原理是创建一个新数组,新数组包含原数组中所有通过指定测试函数的元素。
- filter将传入的回调函数依次作用于每个元素,根据回调函数返回的布尔值(true或false)决定保留或丢弃该元素。
- Array.filter(function(currentValue, index, arr), thisValue)
参数说明:
1. function(currentValue,index,arr):必填
- 数组中的每个元素都会执行这个函数。
- currentValue:必填,表示当前元素的值。
- index:可选,当前元素的索引也就是第几个数组元素。
- arr:可选,当前元素属于的数组对象。
2. thisValue:可选,对象作为该执行回调时使用,传递给函数,用作“this”的值。
let newArray = array.filter(item=>item%2===0).map(item =>item * item)
例3:对原数组中偶数索引位置的元素进行平方后赋值给新数组。
let array = [1, 2, 3, 4];
let newArray = array.filter((item,idx)=>idx%2===0).map(item =>item * item)
例4:巧妙利用 arr 参数,结合indexOf方法给数组去重。
var newArray = array.filter((item,idx,arr)=>arr.indexOf(item) === idx)
例2:对原数组的偶数进行平方后求累加和。
reduce
用于遍历数组,可以设置初始值,大大增强了代码的可读性,同时还有一个参数可以做累计计算。
array.reduce((pre, cur, index, arr),init)
参数说明:
1. function((pre, cur, index, arr)):必填
- pre: 必填,积累值
- cur: 必填。当前元素。
- index: 可选。当前下标。
- arr: 可选。当前数组。
2. init: 可选。传递给函数的初始值,但传入参数为两个时,init 是累计值 pre的初始值。
如果reduce的参数只有一个,那么累计值的初始值是数组的第一个值。
如果reduce的参数有两个,那么积累值初始值就是设置好的 参数init初始值。
在每一次迭代中,返回的值都作为下一次迭代的 pre累计值。
var ans = arr.filter(item=>item%2).map(item=>item*item).reduce((x,y)=>x+y);
箭头函数中的this使用
普通函数中是有this的标识符
function foo(){
console.log("foo",this);
}
foo()//window
foo.apply("aaa")//aaa
箭头函数中,压根没有this。
var bar = ()=>{console.log("bar",this)}
bar()//window
bar.apply("AAA")//window
concat
concat()方法是用于连接两个或多个数组。
var arr = [1, 2, 3, 4];
var arr2 = [7, 8, 9, 10];
var ans = [].concat(arr,arr2);
console.log(ans);//输出:(8) [1, 2, 3, 4, 7, 8, 9, 10]
this的查找规则
因为箭头函数中没有this的标识符,所以当箭头函数内部开始调用this时。
JavaScript引擎会从当前作用域由内向外查找含有this指向的外层作用域。
var obj ={
name:"obj",
foo:function(){
var bar = ()=>{
console.log("bar",this);
}
return bar;
}
}
第一层 bar箭头函数:没有。
第二层 function 函数:指向obj。
所以例子中的 this 指向obj。
var obj ={
name:"obj",
foo:()=>{
var bar =()=>{
console.log("bar:",this);
}
return bar;
}
}
第一层 bar箭头函数:没有。
第二层 foo箭头函数:没有。
第三层 全局作用域:指向window。
所以例子中的 this 指向window。
模拟网络发送请求
封装 request 工具函数
function request(url,callback){
var res = ["abc","cba","nba"];
callback(res);
}
实际操作的位置
早期的写法
因为此时传入 request 的function ,就是 request 定义中的 callback()。
所以 function 中的参数就是 request 定义中的 res 数组,然后赋值给了 此对象中names
但因为 function 是个回调函数的this 的指向是 window,所以需要在外层的函数中,规定一个_this指向当前对象。
var _this = this;
然后 将获取过来的 res 数组 赋值给 _this 中的names
_this.name = [].concat(ans);var obj = {
names:[],
network:function(){
var _this = this;
request("/names",function(ans){
_this.name = [].concat(ans);
})
}
箭头函数的写法
因为箭头函数本身是没有 this的,js引擎会由内往外的找 this的指向。
发现 外层的 函数 this指向obj,于是 this 就指向了 obj。
var obj = {
names:[],
network:function(){
request("/names",(ans)=>{
this.name = [].concat(ans);
})
}到此这篇关于一文带你玩转JavaScript的箭头函数的文章就介绍到这了,更多相关JavaScript 箭头函数内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!