# this ###### tags: `Js` `核心Js` [直接看這篇](https://ithelp.ithome.com.tw/articles/10193193) * this 代表的是 function **執行時所屬的物件**,而不是 function 本身。 * 每個執行環境都有屬於自己的this關鍵字(自然產生) * this與函式如何宣告**沒有關聯性**,僅與呼叫方法有關 * **嚴格模式**下,簡易呼叫會有很大的改變 ![截圖 2024-06-07 下午4.27.08](https://hackmd.io/_uploads/S1tvVrxHC.png) > 百分之95的this指向都是以上(如果前面有物件就指向物件,沒有就指向全域 #### 影響函式 [this](https://blog.techbridge.cc/2019/02/23/javascript-this/) 的調用方式 * 作為物件方法(最常運用 this 的方法) * 簡易呼叫(絕大多數的呼叫方式) * bind, apply, call 方法 * new * DOM 事件處理器 * 箭頭函式(ES6) ![](https://i.imgur.com/jhINWdB.png) (圖片來源:六角學院) > 例 ```javascript= function callName(){ console.log(this, this.myName); } var family = { myName: '小明家', callName: callName, Ming: { myName: '小明', callName: callName } } family.callName(); family.Ming.callName() ``` 回傳: ![](https://i.imgur.com/Ms9deMj.png) ### this 的 [call, apply, bind](https://ithelp.ithome.com.tw/articles/10195896) call、apply、bind 三者都是 JavaScript Function 的內建函式,他們與 this 的關係重大,除此之外,call & apply 可以作為呼叫 Function 的另一個手段,而 bind 則會回傳一個經過包裹後的 Function 回來。 #### call (立刻執行) * 第一個參數: 輸入的物件會被指定為目標函式中的 this * 第二以後的參數: 會作為參數傳進目標函式中,如果目標函式中不需要參數則不要傳入即可 #### apply (立刻執行) * 第一個參數: 輸入的物件會被指定為目標函式中的 this * 第二個參數: 必須是**陣列**,會把陣列中的每個元素作為參數傳進目標函式中,如果目標函式中不需要參數則不要傳入即可 #### bind (非立刻執行) * 明確指定 this * 回傳一個包裹函式,當我們執行這個函式時,同時也會將帶入 bind 的 arguments 一起帶進 Function 中。類似 [Currying](https://jigsawye.gitbooks.io/mostly-adequate-guide/content/ch4.html) 的概念。 全域 ![](https://i.imgur.com/qXc78ke.png) > 例 (call,apply) ```javascript= function fn(this,part1,part2) { console.log(this,part1,part2); } fn.call(family,1,2); fn.apply(family,[3,4]); ``` 因為this會呼叫全域(window)所以會輸出myName:"小明家" ![](https://i.imgur.com/d2AhP4e.png) > 例 (bind) 函式表達式需先呼叫(fn2();)才能執行 ```javascript= var fn2 = fn.bind(family, '小明', '小華'); fn2(); //且不能加入參數 ``` ### 進階 第1筆雖傳入數字與字串但this是物件所以會轉換成物件 ```javascript= fn.call(1, '小明', '小華'); fn.call('文字', '小明', '小華'); fn.call(undefined, '小明', '小華'); ``` 第三行遵循[嚴格模式](https://www.casper.tw/javascript/2017/12/15/javascript-use-strict/) ![](https://i.imgur.com/xPHGMjb.png) ### 嚴格模式 * 加入'use strict'即可運作 * 並不會影響不支援嚴格模式的瀏覽器 * 可依據執行環境設定'use strict' * 透過拋出錯誤的方式消除一些安靜的錯誤(防止小錯誤) * 禁止使用一些有可能被末來版本 ECMAScript 定義的語法 ![](https://i.imgur.com/C3X0hBW.png) 例1 (嚴格模式下不能直接對變數宣告) ```javascript= (function() { 'use strict'; //執行嚴格模式 a = '小明'; }) (): ``` ![](https://i.imgur.com/tf9huIv.png) 例2 ```javascript= function callStrict(part1, part2) { 'use strict'; console.log(this, typeof this, part1, part2); } callStrict.call(1, '小明', '小華'); //維持數字1不會變成建構式 callStrict.call(undefined, '小明', '小華'); //維持undefined不會變成建構式 callStrict('小明', '小華');//簡易呼叫會輸出上次抓到的值 ``` ![](https://i.imgur.com/iI07xDZ.png) > 補充 DOM: ```htmlmixed= <button onclick="console.log(this)">這是一個按鈕</button> //log改成dir可以輸出button ``` ![](https://i.imgur.com/UOWZfyL.png)