在ES6之前,匿名函数一般是这样的:
var fn=function(x,y){ return x+y; }
ES6提供了一种更简单的函数写法,就是箭头函数:
参数 => 函数体
var f = v => v; //等价于 var f = function(v){ return v;} f(1); //1
箭头函数相当于匿名函数,并且简化了函数定义。箭头函数有两种格式,一种像上面的,只包含一个表达式,连{ ... }和return都省略掉了。还有一种可以包含多条语句,这时候就不能省略{ ... }和return:
当箭头函数没有参数或者有多个参数,要用 () 括起来。
var f = (a,b) => a+b; f(6,2); //8
当箭头函数函数体有多行语句,用 {} 包裹起来,表示代码块,当只有一行语句,并且需要返回结果时,可以省略 {} , 结果会自动返回。
var f = (a,b) => { let result = a+b; return result;} f(6,2); // 8
当箭头函数要返回对象的时候,为了区分于代码块,要用 () 将对象包裹起来。因为和函数体的{ ... }有语法冲突,所以要改为:
// 报错 var f = (id,name) => {id: id, name: name}; f(6,2); // SyntaxError: Unexpected token : // 不报错 var f = (id,name) => ({id: id, name: name}); f(6,2); // {id: 6, name: 2}
箭头函数比较匿名函数最大的好处:箭头函数内部的this是词法作用域,由上下文确定。。
箭头函数体中的 this 对象,是定义函数时的对象,而不是使用函数时的对象。
比如以前用匿名函数的时候,this的指向就谁调用该函数,谁就是this:
var oDiv=document.querySelector(".box"); oDiv.onclick=function(){ this.style.backgroundColor="red"; }
但是如果函数里面嵌套了函数,这个时候的this指向就变了。
var oDiv=document.querySelector(".box"); oDiv.onclick=function(){ setTimeout(function(){ this.style.backgroundColor="red"; }, 500); } //Uncaught TypeError: Cannot set property 'backgroundColor' of undefined
因为调用setTimeout定时器的对象已经变成了window对象。
var oDiv=document.querySelector(".box"); oDiv.onclick=function(){ setTimeout(function(){ console.log(this); // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …} }, 500); }
所以,需要先把this保持在一个变量里面。
var oDiv=document.querySelector(".box"); oDiv.onclick=function(){ var _this=this; setTimeout(function(){ _this.style.backgroundColor="red"; }, 500); }
有了箭头函数之后,就不需要再保存变量了,直接使用this就可以了。
var oDiv=document.querySelector(".box"); oDiv.onclick=function(){ setTimeout(()=>{ this.style.backgroundColor="red"; }, 500); }
var Person1 = { 'age': 18, 'sayHello': function () { setTimeout(()=>{ console.log(this.age); }); }}; var age = 20; Person1.sayHello(); // 18
箭头函数中的this是继承父执行上下文里面的this。箭头函数中,this指向的固定化,并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。正是因为它没有this,所以也就不能用作构造函数。
所以,当我们需要维护一个 this 上下文的时候,就可以使用箭头函数。
用在回调函数时候也挺好用。
let arr = [1, 2, 3]; let newArr=arr.map(item => item + 1); console.log(newArr);
不适合使用的场景
1、定义对象的方法,且该方法中包含 this。
此时的箭头函数中的this指向的是window。而匿名函数中的this指向的才是对象本身。
var obj = { a: 10, b: () => { console.log(this.a); // undefined console.log(this); // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …} }, c: function () { console.log(this.a); // 10 console.log(this); // {a: 10, b: ƒ, c: ƒ} } } obj.b(); obj.c();
2、需要动态 this 的时候
var button = document.getElementById('userClick'); button.addEventListener('click', () => { this.classList.toggle('on');}); //此时箭头函数里面的this指向的是外层的this 对象,即 Window,导致无法操作到被点击的按钮对象。 //这种写法也不可以 var oDiv = document.querySelector(".box"); oDiv.onclick = ()=> { this.style.backgroundColor = "red"; } console.log(this); // window
发表评论:
◎请发表你卖萌撒娇或一针见血的评论,严禁小广告。