箭頭函數和普通函數的差別如下:
普通函數:誰調用我,我的this就指向誰。
箭頭函數:我定義在哪個位置,this就指向誰。
總結:
普通函數中的this:
1.this總是代表它的直接調用者, 例如 obj.func ,那麼func中的this就是obj
2.在預設情況,沒找到直接調用者,則this指的是 window,常見的window的屬性和方法有: alert, location,document,parseInt,setTimeout,setInterval等。
3.使用call,apply,bind(ES5新增)綁定的,this指的是綁定的對象。
4.全局作用域下,用var和function聲明定義并調用的變量this都指向window。
示例:
let a = 'zs';
let aa = setTimeout(function () {
console.log(this)//window
console.log(this.a)//undefined
}, 1000);
分析:回調函數的this都指向window,let聲明的變量不指向window
1.第一組比較:
普通函數:
var age = 100;
var obj = {
age: 20,
say: function () {
console.log(this.age)//20
}
}
obj.say()
結果顯示:20
分析:普通函數,誰調用函數,函數的this就指向誰,這裡obj調用say(),是以this指向obj,那obj.age=20,是以列印結果為20。
箭頭函數:
var age = 100;
var obj = {
age: 20,
say: () => {
console.log(this.age)//指向window
}
}
obj.say()
結果顯示:100
分析:箭頭函數,函數的this指向該函數被定義時的位置,function定義時this指向window,第一行用var聲明且指派的變量也指向window,那window.age=100,是以列印結果為100。
2.第二組比較:
普通函數+call:
const obj = { name: '張三' }
function fn() {
console.log(this);//{ name: '張三' }
return function () {
console.log(this);//window,普通函數this指向調用的位置
}
}
const resFn = fn.call(obj);
resFn();
結果顯示:兩次列印的this都指向
window
這個對象。
分析:這次的第8行,fn函數的this指向由
window
變為了
obj
,是以第3行輸出了
{ name: '張三' }
,函數繼續執行,我們看到常量resFn承接了fn函數傳回的一個
函數聲明
,第9行調用了這個函數,這是一個
普通函數
,那它的this指向的是它調用的位置,此時resFn在全局作用域下被調用,那麼這個函數的this應該指向
window
。
箭頭函數:
const obj = { name: '張三' }
function fn() {
console.log(this);//window
return () => {
console.log(this);//window
}
}
const resFn = fn();
resFn();
結果顯示:第一次列印的this都指向
obj
這個對象,第二次this指向
window
。
分析:這次的第8行,fn函數沒有執行call()函數,那由于fn是在全局作用域下定義的函數,此時的function,this指向
window
,是以第2行,輸出為window。第9行調用了這個函數,由于該函數是
箭頭函數
,它的this指向的是
函數定義時
的那個this的指向,這個函數定義在fn裡面,fn的this指向
window
,是以這個箭頭函數也指向
window
箭頭函數+call():
const obj = { name: '張三' }
function fn() {
console.log(this);//{ name: '張三' }
return () => {
console.log(this);//{ name: '張三' }
}
}
const resFn = fn.call(obj);//改變了fn的this指向,指向obj這個對象
resFn();
結果顯示:兩次列印的this都指向
obj
這個對象,輸出結果都是
{ name: '張三' }
。
分析:第8行表明,fn函數的this指向由
window
變為了
obj
,是以第3行輸出了
{ name: '張三' }
,函數繼續執行,我們看到常量resFn承接了fn函數傳回的一個
函數聲明
,第9行調用了這個函數,由于該函數是
箭頭函數
,它的this指向的是
函數定義時
的那個this的指向,這個函數定義在fn裡面,fn的this指向
obj
,是以這個箭頭函數也指向
obj