JavaScript內的this指向
- 在 javascript 語言中, 有一個奇奇怪怪的 "關鍵字" 叫做 this
- 為什麼說它是奇奇怪怪呢, 是因為你寫出 100 個 this, 可能有 100 個解釋, 完全不挨邊
- 但是, 在你的學習過程中, 搞清楚了 this 這個玩意, 那麼會對你的開發生涯有很大幫助的
- 接下來我們們就開始一點一點的認識一下 this
this 初認識
- 看到 this, 先給他翻譯過來 "這個"
- 到底啥意思呢 ?
- 飯桌上, 你媽和你說, 你多吃點的這個
- 商店裡, 你媳婦和你說, 這個包 這個包 這個包 我都要
- 宴會上, 你爸和人介紹說, 這個傻小子是我兒子
- 你看, 每一句話上都有 "這個", 但是每個 "這個" 都是一個意思嗎 ? 並不
- 就像我們 js 內的 this 一樣, 每一個 this 的意思都不一樣
- 但是我們會發現
- 在說話的過程中, "這個" 是和我們說話的手勢有關係
- 在 js 內一個道理
- this 的意思是和程式碼的 "手勢" 有關係
- 例子 :
- 當你媳婦手指著一個 LV 包的時候, 說的 "這個" 指代的就是 LV包`
- 當你媽指著魚香肉絲的時候說 "這個" 指代的就是 魚香肉絲
- 所以在 javascript 內的 this 是要看 "說這句話的程式碼手指向哪裡了"
- 看看下面一段程式碼
var box = document.querySelector('#box')
box.onclick = function () {
console.log(this)
}
- 當你點選 box 這個元素的時候, 會觸發後面的函式
- 然後函式一執行, 就會在控制檯列印一下 this
- 這裡的 this 就是 box 這個元素
- 這就是一個非常簡單的 this 指向的例子了
- 接下來我們就開始詳細學習一下 this
給你個概念
- this , 是一個指標形變數, 它動態的指向當前函式的執行環境
- "什麼鬼東西, 我聽不懂啊"
- 給一個私人的解釋 : "根據 this 所在的函式是如何被呼叫的來決定 this 是什麼"
- 舉個例子來看一下
function fn() {
console.log(this)
}
fn()
// this 就是 window
- 因為 this 是在 fn 函式內, 所以 fn 函式的呼叫方式就決定了這個 this 是什麼
function a() {
function b() {
console.log(this)
}
b()
}
a()
// this 就是 window
- 因為 this 是在 b 函式內, 所以 b 函式的呼叫方式決定了 this 是什麼, 和 a 函式沒關係
- 就是這個意思
- 最後, 根據這些年的經驗總結給出一個私人的概念, 要牢記
- 函式的 this
- 和函式定義在哪沒關係
- 和函式怎麼定義沒關係
- 只看這個函式的呼叫方式
- 箭頭函式除外
物件呼叫
- 物件呼叫, 就是利用一個物件作為宿主來呼叫函式
- 最簡單的方式就是把函式寫在一個物件內, 利用物件來呼叫
// 物件內寫一個函式
const obj = {
fn: function () { console.log(this) }
}
// 呼叫這個函式
obj.fn()
- 這時候, 我們呼叫了和這個物件內的 fn 函式
- 呼叫方式就是利用物件呼叫的函式, 所以在這個函式內的 this 就是 obj 這個物件
- 換句話說, 只要在這個函式內, 只要出現 this 就是這個物件
全域性呼叫
- 顧名思義, 全域性呼叫就是直接呼叫一個全域性函式
function fn() {
console.log(this)
}
fn()
- 此時這個函式內的 this 就是 window
- 可能有的小夥伴覺得瘋了
- 但是我們仔細思考一下, 你會發現
- 其實 fn 因為是在全域性上的, 那麼其實呼叫的完整寫法可以寫成 window.fn()
- 此時就回到了之前物件呼叫那條路上, 這樣就通順了
奇怪的呼叫
- 這個時候, 有的小夥伴可能會想到一個問題, 如果這個函式不放在全域性呢 ?
const obj = {
fn: function () {
function fun() {
console.log(this)
}
fun()
}
}
obj.fn()
- 此時的 this 應該是什麼呢 ?
- 按照之前的思路思考
- obj.fn() 確實呼叫了函式, 但是 this 不是在 obj.fn 函式內, 是在 fun 函式內
- fun() 確實也呼叫了函式, 但是我沒有辦法寫成 window.fun()
- 那麼 this 到底是不是 window 呢, 還是應該是 obj 內
- 答案確實是 window, 這又是為什麼呢 ?
捋一下思路
- 說道這裡, 我們會發現
- this 真的是好奇怪哦 o(* ̄︶ ̄*)o 搞不定了
- 要是按照這個方式, 我來回來去的得記多少種, 誰會記得下來呢
- 接下來(劃重點)
我用我程式碼三十年的經驗給你總結出來了一些內容, 希望你能牢記
this 的個人經驗
- 首先, this 在各種不同的情況下會不一樣
- 那麼從現在開始我把我總結的內容毫無保留的傳授給你
經驗一 :
- 在 js 的非嚴格模式下適用
- 在非箭頭函式中適用
- 不管函式定義在哪, 不管函式怎麼定義, 只看函式的呼叫方式
- 只要我想知道 this 是誰
- 就看這個 this 是寫在哪個函式里面
- 這個函式是怎麼被呼叫的
觀察 this 在哪個函式內
function fn() {
console.log(this)
}
// this 在函式 fn 內, 就看 fn 函式是怎麼被呼叫的就能知道 this 是誰
const obj = {
fn: function () {
console.log(this)
}
}
// this 在 obj.fn 函式內, 就看這個函式怎麼被呼叫的就能知道 this 是誰
const obj = {
fn: function () {
function fun() {
console.log(this)
}
}
}
// 這個 this 是在 fun 函式內
// 如果你想知道這個 this 是誰
// 和 obj.fn 函式沒有關係, 只要知道 fun 函式是怎麼被呼叫的就可以了
- 一定要注意 : 你想知道的 this 在哪個函式內, 就去觀察哪個函式的呼叫方式就好了
一些常見的函式呼叫方式
1.普通呼叫
- 呼叫方式 : 函式名()
- this 是 window
- 只要你書寫 "函式名()" 呼叫了一個函式, 那麼這個函式內的 this 就是 window
function fn() {
console.log(this)
}
fn()
// 這裡就是 fn() 呼叫了一個函式, 那麼 fn 內的 this 就是 window
const obj = {
fn: function () {
function fun() {
console.log(this)
}
fun()
}
}
obj.fn()
// 這裡的 this 因為是在 fun 函式內
// fun() 就呼叫了這個 fun 函式
// 所以不用管 fun 函式寫在了哪裡
// 這個 fun 函式內的 this 就是 window
2.物件呼叫
- 呼叫方式:
- 物件.函式名()
- 物件['函式名']()
- this 就是這個物件, 物件叫啥, 函式內的 this 就叫啥
const obj = {
fn: function () {
console.log(this)
}
}
obj.fn()
// 因為 obj.fn() 呼叫了這個函式, 所以 obj.fn 函式內的 this 就是 obj
const xhl = {
fn: function () {
console.log(this)
}
}
xhl.fn()
// 因為 obj.fn() 呼叫了這個函式, 所以 xhl.fn 函式內的 this 就是 xhl
function fn() {
const xhl = {
fn: function () {
console.log(this)
}
}
xhl.fn()
}
fn()
// 因為我們要觀察的 this 是在 xhl.fn 這個函式內
// 所以只需要關注這個函式是如何被呼叫的即可
// 因為是 xhl.fn 呼叫了和這個函式, 所以函式內的 this 就是 xhl
3.定時器呼叫
- 呼叫方式
- setTimeout(function () {}, 1000)
- setInterval(function () {}, 1000)
- this 就是 window
- 一個函式不管是怎麼定義的, 只要被當做定時器處理函式使用, this 就是 widnow
setTimeout(function () {
console.log(this)
}, 1000)
// 這裡的 this 就是 window
setInterval(function () {
console.log(this)
}, 1000)
// 這裡的 this 就是 window
const xhl = {
fn: function () {
console.log(this)
}
}
setTimeout(xhl.fn, 1000)
// 這裡的 xhl.fn 函式不是直接書寫 xhl.fn() 呼叫的
// 而是給到了 setTimeout 定時器處理函式
// 所以這裡的 this 就是 window
4.事件處理函式
- 呼叫方式
- 事件源.on事件型別 = 事件處理函式
- 事件源.addEventListener(事件型別, 事件處理函式)
- this 就是 事件源
- 只要是作為事件處理函式使用, 那麼該函式內的 this 就是 事件源
奧,對了,事件就是:在事件中,當前操作的那個元素就是事件源
box.onclick = function () {
console.log(this)
}
// 這裡的 this 就是 box
box.addEventListener('click', function () {
console.log(this)
})
// 這裡的 this 就是 box
const xhl = {
fn: function () {
console.log(this)
}
}
box.addEventListener('click', xhl.fn)
// 這裡的 xhl.fn 函式不是直接書寫 xhl.fn() 呼叫的
// 而是給到了 事件, 被當做了事件處理函式使用
// 所以這裡的 this 就是 事件源box
const xhl = {
fn: function () {
console.log(this)
}
}
box.onclick = xhl.fn
// 這裡的 xhl.fn 函式不是直接書寫 xhl.fn() 呼叫的
// 而是給到了 事件, 被當做了事件處理函式使用
// 所以這裡的 this 就是 事件源box
5.建構函式呼叫
- 呼叫方式
- new 函式名()
- this 就是該建構函式的當前例項
- 只要和 new 關鍵字呼叫了, this 就是例項物件
function fn() {
console.log(this)
}
const f = new fn()
// 這裡的因為 fn 函式和 new 關鍵字在一起了
// 所以這裡的 this 就是 fn 函式的例項物件
// 也就是 f
const xhl = {
fn: function () {
console.log(this)
}
}
const x = new xhl.fn()
// 這裡的 xhl.fn 也是因為和 new 關鍵字在一起了
// 所以這裡的 this 就是 xhl.fn 函式的例項物件
// 也就是 x
記清楚原則 :
不管函式在哪定義
不管函式怎麼定義
只看函式的呼叫方式
經驗二 :
- 在嚴格模式下適用
- 其實只有一個
- 全域性函式沒有 this, 是 undefined
- 其他的照搬經驗一就可以了
1.非嚴格模式
// 非嚴格模式
function fn() {
console.log(this)
}
fn()
// 因為是在非嚴格模式下, 這裡的 this 就是 window
2.嚴格模式
// 嚴格模式
'use strict'
function fn() {
console.log(this)
}
fn()
// 因為是在嚴格模式下, 這裡的 this 就是 undefined
記清楚原則 :
嚴格模式下
全域性函式沒有 this
是個 undefiend
經驗三 :
- 專門來說一下箭頭函式
- 其實也只有一條
- 推翻之前的所有內容
- 箭頭函式內沒有自己的 this
- 箭頭函式內的 this 就是外部作用域的 this
- 換句話說, 當你需要判斷箭頭函式內的 this 的時候
- 和函式怎麼呼叫沒有關係了
- 要看函式定義在什麼位置
// 非箭頭函式
const xhl = {
fn: function () {
console.log(this)
}
}
xhl.fn()
// 因為是 非箭頭函式, 所以這裡的 this 就是 xhl
// ==========================================================
// 箭頭函式
const xhl = {
fn: () => {
console.log(this)
}
}
xhl.fn()
// 因為是 箭頭函式, 之前的經驗不適用了
// 這個函式外部其實就是全域性了, 所以這裡的 this 就是 window
// 非箭頭函式
box.onclick = function () {
console.log(this)
}
// 因為是 非箭頭函式, 這裡的 this 就是 box
// ==========================================================
// 箭頭函式
box.onclick = () => {
console.log(this)
}
// 因為是 箭頭函式
// 這個函式外部就是全域性了, 所以這裡的 this 就是 window
// 非箭頭函式
const obj = {
fn: function () {
function fun() {
console.log(this)
}
fun()
}
}
obj.fn()
// 因為是 非箭頭函式, 所以 fun 函式內的 this 就是 window
// ==========================================================
// 箭頭函式
const obj = {
fn: function () {
const fun = () => {
console.log(this)
}
fun()
}
}
obj.fn()
// 因為是 箭頭函式
// 那麼這個 fun 外面其實就是 obj.fn 函式
// 所以只要知道了 obj.fn 函式內的 this 是誰, 那麼 fun 函式內的 this 就出來了
// 又因為 obj.fn 函式內的 this 是 obj
// 所以 fun 函式內的 this 就是 obj
記清楚原則 :
只要是箭頭函式
不管函式怎麼呼叫
就看這個函式定義在了哪裡
最後
- 好了
- 按照以上三個經驗, 記清楚原則
- 那麼在看到 this 就不慌了
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70023145/viewspace-2937877/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- JavaScript 內的 this 指向JavaScript
- JavaScript的this的指向JavaScript
- JavaScript 中 This 的指向JavaScript
- javascript:this指向JavaScript
- javascript的this指向問題JavaScript
- JavaScript中this指向以及改變this指向JavaScript
- JavaScript_this指向JavaScript
- JavaScript中this指向的總結JavaScript
- 關於javascript的this指向問題JavaScript
- JavaScript 的 this 指向問題深度解析JavaScript
- JavaScript中this指向問題JavaScript
- 全面解析JavaScript中this指向JavaScript
- JavaScript 的 this 指向和繫結詳解JavaScript
- 深入理解JavaScript的this指向問題JavaScript
- 【JavaScript】聊聊js中關於this的指向JavaScriptJS
- 函式內部This的指向問題函式
- JavaScript進階教程(4)-函式內this指向解惑call(),apply(),bind()的區別JavaScript函式APP
- 6. JavaScript this指向相關JavaScript
- javascript this指向簡單介紹JavaScript
- 圖解javascript this指向什麼?圖解JavaScript
- JavaScript中this指標指向的徹底理解JavaScript指標
- JavaScript 你真的瞭解this指向嗎JavaScript
- 【JavaScript】徹底明白this在函式中的指向JavaScript函式
- 第149天:javascript中this的指向詳解JavaScript
- [javascript]搞清this的指向只需問兩個問題JavaScript
- javascript 函式作用域中的關鍵字this的指向JavaScript函式
- JavaScript this指向解綁簡單介紹JavaScript
- 圖文解說 JavaScript this 到底指向什麼?JavaScript
- 【28】避免返回handles指向物件內部成分物件
- 前端三部曲:詳解JavaScript中this的指向前端JavaScript
- 合格前端系列第六彈-從指向看JavaScript前端JavaScript
- JS this的指向JS
- js的this指向JS
- javascript基礎修煉(8)——指向FP世界的箭頭函式JavaScript函式
- 走心大白話JavaScript教程(一)理解JS中this指向的小技巧JavaScriptJS
- JavaScript的內建物件JavaScript物件
- js中的this指向JS
- 關於JavaScript中this的指向,你知曉幾分?請速來圍觀!JavaScript