摘要:在這里,如果用箭頭函數,可以這樣改寫箭頭函數并沒有自己的,所以事件處理函數的調用者并不受影響。比如,在需要動態上下文的場景中,使用箭頭函數需要格外地小心,這些場景包括對象的方法原型方法事件的回調構造函數。
前言
年味兒漸散,收拾下心情,繼續敲代碼吧。
對于即將到來金三銀四的求職季,相信不少同學都在默默地做著準備。本系列旨在梳理前端龐雜的知識點,并盡可能通俗易懂地表述出來,也希望能幫到有需要的同學。
這是前端面試題系列的第 5 篇,你可能錯過了前面的篇章,可以在這里找到:
this 的原理以及用法
偽類與偽元素的區別及實戰
如何實現一個圣杯布局?
今日頭條 面試題和思路解析
面試中,我經常會問及 ES6 的知識點,因為平時工作中用得很多。當問到箭頭函數時,不少候選人都會贊嘆地說:箭頭函數很好用,而且再也不用操心 this 的指向了。
我接著問:箭頭函數是挺好用的,但是你有沒有遇到過,不適合使用箭頭函數的場景呢?
這時,能回答得上來的候選人就很少了。箭頭函數在大多數情況下,是很好用的,但是為什么在有些場景,使用箭頭函數后會產生問題?是不是箭頭函數還不夠完善?又有哪些場景會發生問題?該如何解決呢?這,正是本文想要一起探討的。
箭頭函數的寫法為什么叫箭頭函數( Arrow Function )?因為它的寫法,看上去就是一個箭頭:
const multiply = num => num * num;
它等價于:
const multiply = function (num) { return num * num; };
此外,還可以傳多個參數,以及可變參數。
// 多參數 const multiply = (num1, num2) => num1 * num2; // 可變參數 const sum = (num1, num2, ...rest) => { let result = num1 + num2; for (let i = 0; i < rest.length; i++) { result += rest[i]; } return result; };
當有多條語句時,需要配上 {...} 和 return。
另外,如果返回的結果是對象,則需要配上 (),像下面這樣:
const func = val => ({ value: val });
從上述的寫法來看,相較普通函數而言,箭頭函數的確簡便了很多,提升了我們代碼的易用性。但它并非在任何場景下都適用,接下來,將會介紹幾種不適合箭頭函數的場景,并會提出可行的解決方案。
不適合的場景 1、對象的方法看下面這個例子:
const obj = { x: 1, print: () => { console.log(this === window); // => true console.log(this.x); // undefined } }; obj.print();
this.x 打印出來是 undefined。為什么?然后,我在上面加了一行,發現 this 指向了 window。
解析:print 方法用了箭頭函數,其內部的 this 指向的還是上下文 window,上下文中并沒有定義 x,所以 this.x 輸出為 undefined。
解決辦法:用 ES6 的短語法,或者傳統的函數表達式都可以。所以,print 要這樣寫:
print () { console.log(this === test); // => true console.log(this.x); // 1 }2、原型方法
同樣的規則也適用于原型方法的定義,使用箭頭函數會導致運行時的執行上下文錯誤。
function Cat (name) { this.name = name; } Cat.prototype.sayCatName = () => { console.log(this === window); // => true return this.name; }; const cat = new Cat("Miao"); cat.sayCatName(); // => undefined
解決辦法是:用回傳統的函數表達式,像下面這樣:
Cat.prototype.sayCatName = function () { console.log(this === cat); // => true return this.name; };
sayCatName 變回傳統的函數表達式之后,被調用時的執行上下文就會指向新創建的 cat 實例。
3、事件的回調看下面這個例子:
const btn = document.getElementById("myButton"); btn.addEventListener("click", () => { console.log(this === window); // => true this.innerHTML = "Clicked button"; });
這里會有問題,因為 this 指向了 window。
解析:當為一個 DOM 事件綁定回調函數后,觸發回調函數時的 this,需要指向當前發生事件的 DOM 節點,也就是這里的 btn。當回調發生時,瀏覽器會用 btn 的上下文去調用處理函數。所以最后的 this.innerHTML 等價于 window.innerHTML,問題就在這里。
解決辦法:用函數表達式代替箭頭函數。像這樣:
btn.addEventListener("click", function() { console.log(this === btn); // => true this.innerHTML = "Clicked button"; });
另外,在 react 中的事件回調,也經常會遇到類似的問題。
// jsx render // callback handleClickButton () { ... }
注意:這里 onClick 的回調函數,并非字符串,而是一個實實在在的函數。可以將 onClick 理解為一個中間變量,所以 react 在處理函數時的 this 指向就會丟失。
為了解決這個問題,我們需要為回調函數綁定 this,使得事件處理函數無論如何傳遞,this 都指向我們實例化的那個對象。
在這里,如果用箭頭函數,可以這樣改寫:
箭頭函數并沒有自己的 this,所以事件處理函數的調用者并不受影響。
4、構造函數箭頭函數不能通過 new 關鍵字調用。
const Message = (text) => { this.text = text; }; var helloMessage = new Message("Hello World!"); // Uncaught TypeError: Message is not a constructor
解析:從報錯信息可以看出,箭頭函數沒有 constructor 方法,所以不能用作構造函數。 JavaScript 會通過拋出異常的方式,進行隱式地預防。
解決方法:用函數表達式代替箭頭函數。
總結回顧 MDN 給出的解釋:箭頭函數表達式的語法比函數表達式更短,并且沒有自己的this,arguments,super或 new.target。這些函數表達式更適用于那些本來需要匿名函數的地方,并且它們不能用作構造函數。
所以說,箭頭函數無疑是 ES6 帶來的重大改進,在正確的場合使用箭頭函數,能讓代碼變得更加簡潔短小。但箭頭函數也不是萬能的,不能用的時候,千萬別硬往上套。比如,在需要動態上下文的場景中,使用箭頭函數需要格外地小心,這些場景包括:對象的方法、原型方法、事件的回調、構造函數。并非一定要用箭頭函數,才能解決問題。
PS:歡迎關注我的公眾號 “超哥前端小棧”,交流更多的想法與技術。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/101575.html
摘要:但是有一個總的原則那就是總會指向,調用函數的那個對象。作為對象方法的調用函數作為某個對象的方法調用,這時就指這個上級對象。 showImg(https://segmentfault.com/img/bVbnvF7?w=750&h=422); 這是前端面試題系列的第 4 篇,你可能錯過了前面的篇章,可以在這里找到: 偽類與偽元素的區別及實戰 如何實現一個圣杯布局? 今日頭條 面試題和思...
摘要:原題如下寫一個方法,當使用下面的語法調用時,能正常工作這道題要考察的,就是對函數柯里化的理解。當參數只有一個的時候,進行柯里化的處理。這其實就是函數柯里化的簡單應用。 showImg(https://segmentfault.com/img/bVbopGm?w=620&h=350); 前言 這是前端面試題系列的第 6 篇,你可能錯過了前面的篇章,可以在這里找到: ES6 中箭頭函數的...
摘要:并總結經典面試題集各種算法和插件前端視頻源碼資源于一身的文檔,優化項目,在瀏覽器端的層面上提升速度,幫助初中級前端工程師快速搭建項目。 本文是關注微信小程序的開發和面試問題,由基礎到困難循序漸進,適合面試和開發小程序。并總結vue React html css js 經典面試題 集各種算法和插件、前端視頻源碼資源于一身的文檔,優化項目,在瀏覽器端的層面上提升速度,幫助初中級前端工程師快...
摘要:并總結經典面試題集各種算法和插件前端視頻源碼資源于一身的文檔,優化項目,在瀏覽器端的層面上提升速度,幫助初中級前端工程師快速搭建項目。 本文是關注微信小程序的開發和面試問題,由基礎到困難循序漸進,適合面試和開發小程序。并總結vue React html css js 經典面試題 集各種算法和插件、前端視頻源碼資源于一身的文檔,優化項目,在瀏覽器端的層面上提升速度,幫助初中級前端工程師快...
閱讀 3479·2023-04-25 22:45
閱讀 1281·2021-11-11 16:54
閱讀 2789·2019-08-30 15:44
閱讀 3188·2019-08-30 15:44
閱讀 1645·2019-08-30 13:55
閱讀 940·2019-08-29 18:45
閱讀 1195·2019-08-29 17:25
閱讀 1006·2019-08-29 12:59