箭头函数特点
定义:箭头函数是se6新定义的函数形式,语法比函数表达式更简洁,并且没有自己的this
,arguments
,super
或new.target
。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。
箭头函数特点:
1.语法简单:
使用较为简洁的语法、较少的代码量来完成和普通函数一样的函数,例如:
//普通函数 [1,2,34,5].forEach(function(item,index){ console.log(item,index) }) //箭头函数 [1,2,3,4,5,6].forEach((item,index)=>console.log(item,index))
2.不绑定this
在es5中我们知道函数中this指向问题,得出一个结论:this永远指向函数调用者,但是在箭头函数中,没有this,所以他的指向移动定义时候的所在环境,比如函数的执行期环境,对象环境或者window,例如:
//函数this指向window let test = ()=>console.log(this) test()//window //对象中this指向 let obj = { name: 'jeck', test1: function(){console.log(this)}, test2: ()=>console.log(this) } obj.test1()//{name: "jeck", test1: ƒ, test2: ƒ} obj.test2()//window //函数的this指向 function Person() { this.age = 0; this.num = 0; setTimeout(() => { this.age++; console.log(this.age)//1 }, 3000); setTimeout(function(){ this.num++; console.log(this.num)//NaN }, 3000); } var p = new Person();
在上面代码中,分别在window,对象和函数中分别使用普通函数和箭头函数,输出的值都不一样,使用settimeout,普通函数的this指向是调用者,调用者为window全局对象,没有全局属性,就会报错;箭头函数的this指向为函数定义者,所以可以获取到对应的值。
3.不支持call()和apply()函数的特性
我们都知道call和apply方法可以改变一个函数执行主体,即改变调用函数中this指向,但是箭头函数不能达到这一点,因为他没有this,是继承父作用域的this
let adder = { base : 1, add : function(a) { var f = v => v + this.base; return f(a); }, addThruCall: function(a) { var f = v => v + this.base; var b = { base : 2 }; return f.call(b, a); } }; console.log(adder.add(1)); // 2 console.log(adder.addThruCall(1)); // 2
执行adder.add(1)时,add()函数内部通过箭头函数的形式定义了f()函数,f()函数中的this会继承至父作用域,即adder,那么this.base = 1,因此执行adder.add(1)相当于执行1 + 1的操作,结果输出“2”。
执行adder.addThruCall(1)时,addThruCall()函数内部通过箭头函数定义了f()函数,其中的this指向了adder。虽然在返回结果时,通过call()函数调用了f()函数,但是并不会改变f()函数中this的指向,this仍然指向adder,而且会接收参数a,因此执行adder.addThruCall(1)相当于执行1 + 1的操作,结果输出“2”。
因此在使用call()函数和apply()函数调用箭头函数时,需要谨慎。
4.不绑定arguments
在普通函数中可以使用arguments来获取实际传入的参数值,但是在箭头函数中,我们却无法做到这一点。
const fn = () => { console.log(arguments); }; fn(1, 2); // Uncaught ReferenceError: arguments is not defined
因为无法在箭头函数中使用arguments,同样也就无法使用caller和callee属性。
虽然我们无法通过arguments来获取实参,但是我们可以借助rest运算符(...)来达到这个目的。
const fn = (...args) => { console.log(args); }; fn(1, 2); // [1, 2]
箭头函数不适用的场景:
1.不适合作为对象的函数
在上面代码中,我有讲到箭头函数并不会绑定this,如果使用箭头函数定义对象字面量的函数,那么其中的this将会指向外层作用域,并不会指向对象本身,因此箭头函数并不适合作为对象的函数。
2. 不能作为构造函数
不能使用new操作符
构造函数是通过new操作符生成对象实例的,生成实例的过程也是通过构造函数给实例绑定this的过程,而箭头函数没有自己的this。因此不能使用箭头函数作为构造函数,也就不能通过new操作符来调用箭头函数。
function Person(name) { this.name = name; } var p = new Person('kingx'); // 正常 // 箭头函数 let Person = (name) => { this.name = name }; let p = new Person('kingx'); // Uncaught TypeError: Person is not a constructor
3. 没有prototype属性
因为在箭头函数中是没有this的,也就不存在自己的作用域,因此箭头函数是没有prototype属性的。
let a = () => { return 1; }; function b(){ return 2; } console.log(a.prototype); // undefined console.log(b.prototype); // {constructor: ƒ}
希望对大家有用,感谢支持!