js關於數組的面試題(JS關於this)
2023-10-17 12:48:01 2
this 關鍵字是 JavaScript 中最複雜的機制之一。它是一個很特別的關鍵字,被自動定義在 所有函數的作用域中。但是即使是非常有經驗的 JavaScript 開發者也很難說清它到底指向 什麼。
實際上,JavaScript 中 this 的機制並沒有那麼先進,但是開發者往往會把理解過程複雜化, 毫無疑問,在缺乏清晰認識的情況下,this 對你來說完全就是一種魔法。
為什麼要用this這段代碼可以在不同的上下文對象(me 和 you)中重複使用函數 identify 和 speak, 不用針對每個對象編寫不同版本的函數
如果不使用 this,那就需要給 identify 和 speak 顯式傳入一個上下文對象。
然而,this 提供了一種更優雅的方式來隱式「傳遞」一個對象引用,因此可以將 API 設計 得更加簡潔並且易於復用。
誤解我們之後會解釋 this 到底是如何工作的,但是首先需要消除一些關於 this 的錯誤認識。
太拘泥於「this」的字面意思就會產生一些誤解。有兩種常見的對於 this 的解釋,但是它 們都是錯誤的。
指向自身人們很容易把 this 理解成指向函數自身,這個推斷從英語的語法角度來說是說得通的。
那麼為什麼需要從函數內部引用函數自身呢?常見的原因是遞歸(從函數內部調用這個函 數)或者可以寫一個在第一次被調用後自己解除綁定的事件處理器。
JavaScript 的新手開發者通常會認為,既然函數看作一個對象(JavaScript 中的所有函數都 是對象),那就可以在調用函數時存儲狀態(屬性的值)。這是可行的,有些時候也確實有 用,但是後面即將介紹的許多模式中你會發現,除了函數對象還有許多更合適存儲狀態 的地方。
我們想要記錄一下函數 foo 被調用的次數,思考一下下面的代碼:
console.log 語句產生了 4 條輸出,證明 foo(..) 確實被調用了 4 次,但是 foo.count 仍然 是 0。顯然從字面意思來理解 this 是錯誤的。
執行 foo.count = 0 時,的確向函數對象 foo 添加了一個屬性 count。但是函數內部代碼 this.count 中的 this 並不是指向那個函數對象,所以雖然屬性名相同,根對象卻並不相 同,困惑隨之產生。
遇到這樣的問題時,許多開發者並不會深入思考為什麼 this 的行為和預期的不一致,也不 會試圖回答那些很難解決但卻非常重要的問題。他們只會迴避這個問題並使用其他方法來 達到目的,比如創建另一個帶有 count 屬性的對象。
從某種角度來說這個方法確實「解決」了問題,但可惜它忽略了真正的問題——無法理解 this 的含義和工作原理——而是返回舒適區,使用了一種更熟悉的技術:詞法作用域
所以,對於我們的例子來說,另一種解決方法是使用 foo 標識符替代 this 來引用函數 對象:
然而,這種方法同樣迴避了 this 的問題,並且完全依賴於變量 foo 的詞法作用域。
另一種方法是強制 this 指向 foo 函數對象:
這次我們接受了 this,沒有迴避它。如果你仍然感到困惑的話,不用擔心,之後我們會詳 細解釋具體的原理
,