摘要:注意因為箭頭函數(shù)內(nèi)部的是指向外層代碼塊的最近的,例中的函數(shù)的,所以我們可以通過改變外層代碼塊的的指向從而改變箭頭函數(shù)中的指向例中使用了函數(shù)的方法。
一、this關(guān)鍵字小測試
ES6箭頭函數(shù)體中的this指向哪里?
在回答這個問題之前先來揣揣你對this關(guān)鍵字的了解程度:
(讓我們回到ES6之前)
題:
var obj = { a: function() { console.log(this); } } var b = obj.a; b();
問:打印出的this的值?
再來幾個選項:
window
obj
document
obj.a
答案是window(可以在控制臺運(yùn)行一下)
什么!什么情況!發(fā)生了什么?
一句話解釋:
一般的,this指向函數(shù)運(yùn)行(調(diào)用)時所在的執(zhí)行環(huán)境【《JavaScript高級程序設(shè)計》4.2節(jié)執(zhí)行環(huán)境及作用域】的(變量)對象(簡單地,this指向函數(shù)的調(diào)用者)
分析代碼:
var b = obj.a; // ==>相當(dāng)于 var b = function() { console.log(this); }
函數(shù)調(diào)用時(b();)其所在的執(zhí)行環(huán)境是全局環(huán)境,所以this指向全局變量對象window
二、ES6箭頭函數(shù)如果你覺得以上這些都知道了(我會!我會?。┠敲淳屠^續(xù)吧~~
(來到ES6箭頭函數(shù))
例1【阮一峰《ECMAScript 6 入門》-7.函數(shù)的擴(kuò)展:箭頭函數(shù)】
我將阮老師的例子代碼修改了一下:
(普通函數(shù))
function foo() { console.log("id1:", this.id); console.log("this1:", this); setTimeout(function() { console.log("id2:", this.id); console.log("this2:", this); }, 0); } var id = 21; foo(); // Chrome // id1: 21 // this1: window // id2: 21 // this2: window foo.call({id: 42}); // Chrome // id1: 42 // this1: {id: 42} // id2: 21 // this2: window
注意:超時調(diào)用(setTimeout回調(diào))的代碼都是在全局作用域環(huán)境中執(zhí)行的,因此(setTimeout回調(diào))函數(shù)中this的值在非嚴(yán)格模式下指向window對象,在嚴(yán)格模式下是undefined
例如
var obj = { console.log(this); setTimeout(function() { console.log(this); }, 0); } obj.a(); // Chrome // {a: f} // window
回到例1
我們使用foo函數(shù)的call方法改變了foo函數(shù)調(diào)用時函數(shù)體內(nèi)this的指向({id: 42}這個對象),但setTimeout回調(diào)函數(shù)中的this依舊指向window對象(因為在全局環(huán)境中運(yùn)行)。
接下來再將例1改寫一下,將foo函數(shù)中的setTimeout回調(diào)函數(shù)改成箭頭函數(shù)的形式:
例2
(箭頭函數(shù))
function foo() { console.log("id1:", this.id); console.log("this1:", this); setTimeout(() => { console.log("id2:", this.id); console.log("this2:", this); }, 0); } var id = 21; foo(); // Chrome // id1: 21 // this1: window // id2: 21 // this2: window foo.call({id: 42}); // Chrome // id1: 42 // this1: {id: 42} // id2: 42 // this2: {id: 42}
foo();的輸出結(jié)果沒有變化,但foo.call({id: 42});的輸出結(jié)果改變了。
到底發(fā)生了什么?
在這里直接給出結(jié)論:
箭頭函數(shù)根本沒有自己的this,導(dǎo)致內(nèi)部的this指向了外層代碼的this,這個指向在定義時就已經(jīng)確定而不會在調(diào)用時指向其執(zhí)行環(huán)境的(變量)對象。
注意:因為箭頭函數(shù)內(nèi)部的this是指向外層代碼塊的this(最近的this,例2中的foo函數(shù))的,所以我們可以通過改變外層代碼塊的this的指向從而改變箭頭函數(shù)中this的指向(例2中使用了foo函數(shù)的call方法)。
重新解釋例2
因為箭頭函數(shù)(setTimeout回調(diào))沒有自己的this,導(dǎo)致其內(nèi)部的this引用了外層代碼塊的this,即foo函數(shù)的this,
(要注意:在定義階段(調(diào)用函數(shù)前),foo函數(shù)的this的值并不確定【《JavaScript高級程序設(shè)計》第三版5.5.4函數(shù)內(nèi)部屬性】,但箭頭函數(shù)的this自定義階段開始就指向foo函數(shù)的this了)
又因為使用call方法改變了foo函數(shù)運(yùn)行(調(diào)用)時其函數(shù)體內(nèi)this的指向(重新指向?qū)ο?b>{id: 42})從而使箭頭函數(shù)中this的指向發(fā)生變化,最后輸出例2所示結(jié)果。
三、例子總結(jié)到這里,我想小伙伴們應(yīng)該是比較清楚了,那么不妨去看看阮一峰老師的《ECMAScript 6 入門》函數(shù)的擴(kuò)展一節(jié)箭頭函數(shù)部分的一個問題示例:“請問下面的代碼中有幾個this(滑稽)”
加深印象
例3【阮一峰《ECMAScript 6 入門》-19.Class基本語法:this的指向】
class Logger { constructor() { this.printName = (name = "there") => { this.print(`Hello ${name}`); }; } // ... }
箭頭函數(shù)中的this指向constructor構(gòu)造方法內(nèi)部的this,由于此時constructor中的this尚未獲得值,當(dāng)通過new命令生成對象實例時,將會自動調(diào)用constructor方法,constructor的this才能指向該實例對象,在此過程中,箭頭函數(shù)中的this一直引用著constructor中的this,當(dāng)constructor中this發(fā)生變化,箭頭函數(shù)的this也會一并發(fā)生變化。
若有錯誤,請指出批評!!
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/93762.html
摘要:在函數(shù)方面的擴(kuò)展比較豐富也很實用,本篇概括了這中的精華知識。所以無法成為構(gòu)造函數(shù),不能使用操作符。參數(shù)將擴(kuò)展運(yùn)算符作用于參數(shù),即為參數(shù)。聲明式,直接為函數(shù)名。通過構(gòu)造函數(shù)生成的,為。函數(shù)的屬性,在其描述對象的屬性上,為函數(shù)名。 ES6在函數(shù)方面的擴(kuò)展比較豐富也很實用,本篇概括了這中的精華知識。 1 箭頭函數(shù) 箭頭函數(shù)是ES6中定義函數(shù)的新形式。 新形式不僅簡化了定義方式,更為函數(shù)本身...
摘要:正是因為它沒有,所以也就不能用作構(gòu)造函數(shù)。不可以當(dāng)作構(gòu)造函數(shù),也就是說,不可以使用命令,否則會拋出一個錯誤。不可以使用對象,該對象在函數(shù)體內(nèi)不存在。 箭頭函數(shù) 在之前ES5的版本中,我們定義一個函數(shù)的形式如下: function a() { // do something…… } 但是在ES6中,則新增了箭頭函數(shù)的方式,ES6中允許使用箭頭(=>)來定義函數(shù)。 () => { ...
摘要:基礎(chǔ)語法參數(shù)參數(shù)參數(shù)函數(shù)聲明參數(shù)參數(shù)參數(shù)表達(dá)式單一相當(dāng)于參數(shù)參數(shù)參數(shù)表達(dá)式當(dāng)只有一個參數(shù)時,圓括號是可選的單一參數(shù)函數(shù)聲明單一參數(shù)函數(shù)聲明沒有參數(shù)的函數(shù)應(yīng)該寫成一對圓括號。 溫馨提示:作者的爬坑記錄,對你等大神完全沒有價值,別在我這浪費(fèi)生命溫馨提示-續(xù):你們要非得看,我也攔不住,但是至少得準(zhǔn)備個支持ES6的Chrome瀏覽器吧? 之前在某些大神的代碼中出現(xiàn)一串神秘符號類似于num =>...
摘要:第二種情況是箭頭函數(shù)的如果指向普通函數(shù)它的繼承于該普通函數(shù)。箭頭函數(shù)的指向全局,使用會報未聲明的錯誤。 showImg(https://segmentfault.com/img/remote/1460000018610072?w=600&h=400); 箭頭函數(shù)是ES6的API,相信很多人都知道,因為其語法上相對于普通函數(shù)更簡潔,深受大家的喜愛。就是這種我們?nèi)粘i_發(fā)中一直在使用的API...
摘要:對象的指向是可變的,但是在箭頭函數(shù)中,它是固定的。同樣的由于箭頭函數(shù)沒有自己的所以傳統(tǒng)的顯性綁定無效內(nèi)部的指向外部在的學(xué)習(xí)中,的指向問題一直是個難點,特別是在對象方法中使用時,必須更加小心。由此箭頭函數(shù)在很大程度上減少了我們的困擾。 什么是箭頭函數(shù) 用法 ES6 允許使用箭頭(=>)定義函數(shù) 測試 var p1 = document.getElementById(test1)...
閱讀 1550·2021-11-04 16:10
閱讀 2806·2021-09-30 09:48
閱讀 2849·2019-08-29 11:31
閱讀 1587·2019-08-28 18:22
閱讀 3239·2019-08-26 13:44
閱讀 1329·2019-08-26 13:42
閱讀 2855·2019-08-26 10:20
閱讀 764·2019-08-23 17:00