最近遇到一個面試題氏豌,被問到箭頭函數(shù)和普通函數(shù)中的this區(qū)別亿卤,總結(jié)了一下拿出來跟大家分享一下愤兵。
首先知道一下什么是箭頭函數(shù),箭頭函數(shù)就是沒有function關(guān)鍵字排吴,而是一個類似箭頭的函數(shù):
var a = ()=>{
return 1;
}
相當于
function a(){
return 1;
}
那么就來看一下他們的區(qū)別
普通函數(shù)中的this:
1. this總是代表它的直接調(diào)用者, 例如 obj.function ,那么function中的this就是obj;
2.在默認情況(非嚴格模式下,未使用 'use strict'),沒找到直接調(diào)用者,則this指的是 window;
3.在嚴格模式下,沒有直接調(diào)用者的函數(shù)中的this是 undefined;
4.使用call,apply,bind(ES5新增)綁定的,this指的是 綁定的對象秆乳。
箭頭函數(shù)中的this:
1.箭頭函數(shù)會捕獲其所在上下文的 this 值,作為自己的 this 值傍念,自己本身并沒有this值矫夷;
2.箭頭函數(shù)的this永遠指向其上下文的this,任何方法都改變不了其指向憋槐,如call(), bind(), apply()。
1.箭頭函數(shù)作為匿名函數(shù),是不能作為構(gòu)造函數(shù)的,不能使用new
var B = ()=>{
value:1;
}
var b = new B();
//報錯提示:Uncaught TypeError: B is not a constructor
2.箭頭函數(shù)不綁定arguments,取而代之用rest參數(shù)…解決
function A(a){
console.log(arguments); //[object Arguments] {0: 1}
}
var B = (b)=>{
console.log(arguments); //ReferenceError: arguments is not defined
}
var C = (...c)=>{ //...c即為rest參數(shù)
console.log(c); //[3]
}
A(1);
B(2);
C(3);
3.箭頭函數(shù)會捕獲其所在上下文的 this 值淑趾,作為自己的 this 值
var obj = {
a: 10,
b: function(){
console.log(this.a); //10
},
c: function() {
return ()=>{
console.log(this.a); //10
}
}
}
obj.b();
obj.c()();
箭頭函數(shù)當方法使用的時候沒有定義this綁定阳仔。
這句話是MDN里面寫的,但是我覺得這條和上條其實是一條扣泊,還是捕獲所在的上下文近范,比如下面這個例子:b是一個箭頭函數(shù),然后它的 this是指向window延蟹,這是為什么呢评矩,因為箭頭函數(shù)捕獲的是obj{}這個對象的環(huán)境,然后這個環(huán)境的this指向的是window阱飘,就相當于上一條的例子:在c方法里面return的那個箭頭函數(shù)捕獲的是c:function(){}這個環(huán)境的this斥杜,而這個環(huán)境的this是obj,這樣是不是就清晰明了了
var obj = {
a: 10,
b: () => {
console.log(this.a); //undefined
console.log(this); //window
},
c: function() {
console.log(this.a); //10
console.log(this); //obj{...}
}
}
obj.b();
obj.c();
使用call()和apply()調(diào)用
通過 call() 或 apply() 方法調(diào)用一個函數(shù)時沥匈,只是傳入了參數(shù)而已蔗喂,對 this并沒有什么影響
var obj = {
a: 10,
b: function(n){
var f = (v) => v + this.a;
return f(n);
},
c: function(n) {
var f = (v) => v + this.a;
var m = {a:20};
return f.call(m,n);
}
}
console.log(obj.b(1)); //11
console.log(obj.c(1)); //11
箭頭函數(shù)沒有原型屬性
var a = ()=>{
return 1;
}
function b(){
return 2;
}
console.log(a.prototype);//undefined
console.log(b.prototype);//object{...}
箭頭函數(shù)不能當做Generator函數(shù),不能使用yield關(guān)鍵字
箭頭函數(shù)不能換行
var a = ()
=>1; //SyntaxError: Unexpected token =>
大概總結(jié)了這些,先這樣吧高帖,往后接觸的更多一些缰儿,了解的就會更深入一些,到時候再繼續(xù)分享吧散址。