题目
谈谈箭头函数与普通函数的区别。
箭头函数是面试常考的知识点,它与普通函数最大的区别就在于this指向。
解析
下面具体谈谈两者有哪些区别:
-
箭头函数相当于匿名函数,不能作为构造函数,不能使用new
let Fun = () => { console.log('箭头函数'); } let fun = new Fun();
-
箭头函数不能绑定arguments,使用rest参数…代替
function A(a) { console.log(arguments);// [1, 2, 3, 4, 5, callee: ƒ, Symbol(Symbol.iterator): ƒ] } A(1, 2, 3, 4, 5); let B = (b) => { console.log(arguments);// Uncaught ReferenceError: arguments is not defined } B(1, 2, 3, 4, 5); let C = (...c) => { console.log(c);// [1, 2, 3, 4, 5] } C(1, 2, 3, 4, 5);
-
箭头函数中的this始终指向其父级作用域中的this。换句话说,箭头函数会捕获其所在的上下文的this值,作为自己的this值。在箭头函数中调用 this 时,仅仅是简单的沿着作用域链向上寻找,找到最近的一个 this 拿来使用,它与调用时的上下文无关。
var obj = { a: 10, b: () => { console.log(this.a);// undefined console.log(this);// Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …} }, c: function() { console.log(this.a);// 10 console.log(this);// {a: 10, b: ƒ, c: ƒ, d: ƒ} }, d: function () { return () => { console.log(this.a);// 10 } } } obj.b(); obj.c(); obj.d()()
上例中: obj.b()中的this会继承父级上下文中的this值,也就是window。
obj.c()的this指向即为调用者obj,obj.d()()的this也是继承父级上下文中的this, 即d的this指向为obj. -
箭头函数不能通过call()或apply改变this指向。也是接上一条,因为没有自己的this
-
箭头函数没有原型
var a = ()=>{ return 1; } function b(){ return 2; } console.log(a.prototype); // undefined console.log(b.prototype); // {constructor: ƒ}
-
箭头函数不能当作Generator函数,不能使用yield关键字
总结
- 普通函数的this总是指向它的直接调用者。
- 在严格模式下,没找到直接调用者,则函数中的this是undefined。
- 在默认模式下(非严格模式),没找到直接调用者,则函数中的this指向window。
- 箭头函数的 this 永远指向其上下文的 this ,任何方法都改变不了其指向,如 call() , bind() , apply()