iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 21
1
Modern Web

【這些年我似是非懂的 Javascript】系列 第 21

【這些年我似是非懂的 Javascript】Day 21 - 是這個不是那個的 this # Part 1.

這個 this 到底是什麼,對於使用 JS 的你知道 this 這關鍵字他的參考到底是什麼你知道嗎?

反正我是不知道拉
如果你也不知道歡迎跟我一起學習

this 到底是什麼可以吃嗎?

答案很明顯是不行(廢話),
但是他是一個物件,然後裡面的值取決於你執行的函式。
先來談談他的好處

function foo(){
    return this.name.toUpperCase();
}

function boo(){
    const helloStr = `Hello, My name is ${foo.call(this)}`
    console.log(helloStr)
}

const me = {
    name: "Robin"
}

foo.call(me); // ROBIN
boo.call(me); // Hello, My name is ROBIN

那如果說不用這個方式會以什麼方式寫呢?
就是傳入一個 object

function foo(context){
    return context.name.toUpperCase();
}

function boo(context){
    const helloStr = `Hello, My name is ${foo(context)}`
    console.log(helloStr)
}

const me = {
    name: "Robin"
}

foo(me); // ROBIN
boo(me); // Hello, My name is ROBIN

這看起來沒什麼太大的問題,
但是使用 this 的話看起來明顯乾淨了許多,
如果使用的情境越複雜,差異越是明顯。

不負責的言論:書上說之後在物件與原型那章節會提到一群函式能夠自動參考適當的情境物件是一件非常美妙的事(聽起來是作者本身感同身受xDD

你知道嗎?

其實 this 是參考到函式本身,

你現在的想法如果是"真的假的?",
那恭喜你可以繼續看下去,
如果你現在的想法是"聽你在屁!",
請先放下你的怒火,

你想得沒錯!
其實 this 不是參考到函式本身,
在字面上或文法上合理的推論,
可是實際上想想...
什麼情況會想要參考到函式本身xDD?
大概只有想要自己 call 自己進行遞迴之類的,
那如果真的是這樣那以下的範例應該可以 work!

function foo(countFoo){
    console.log(`foo-> ${countFoo}`);
    this.count++;
}

foo.count = 0;

for(let i=0; i<5; i++){
    foo(i);
}
// foo-> 0
// foo-> 1
// foo-> 2
// foo-> 3
// foo-> 4


console.log(foo.count); // 0 , 說好的 5 呢?

實際上看起來就不是對吧!?
所以我們要拋開他字面上的意思...

其實它就是...
"this 執行時期的繫結",主要他會取決於函式調用的各種條件為基礎,this 的繫結與函式在何處被宣告無關,單純就是取決於函式被呼叫的方式。

那...所以他到底怎麼知道 this 被用什麼方式呼叫?

其實就是當一個函式被調用時會有一個"啟動紀錄"被創建出來,也被叫做"執行情境",他裡面就包含了很多資訊包含該函式式在哪裡被調用的傳入什麼參數等等的,

講那麼多啊上面那個我該如何用 this 給他大大的擁抱?

function foo(countFoo){
    console.log(`foo-> ${countFoo}`);
    this.count++;
}

foo.count = 0;

for(let i=0; i<5; i++){
    foo.call(foo,i);
}
// foo-> 0
// foo-> 1
// foo-> 2
// foo-> 3
// foo-> 4


console.log(foo.count); // 5

差異再哪?

主要是透過 call() 確保 this 指向該函式物件本身。

以上是今天的內容
如果看不懂也沒關係明天會學會如何找出一個函式的呼叫地點和他執行過程是如何繫結 this 的 (書上說的xD)


今天是鐵人賽第 21 天,越來越鐵人 xD
生活中滿多意外會造成原本的行程有變化,
俗話說的好"計劃趕不上變化",
例如我現在就只剩下兩個小時要寫文章加看書,
我都好奇我真的有時間內化嗎 Orz ?
我只能盡量先縮減今天要看的內容
我感到非常抱歉Orz

感謝你
我們明天見


參考來源:

你所不知道的 JS|範疇與 Closures,this 與物件原型 (You Don't Know JS: this & Object Prototypes))


上一篇
【這些年我似是非懂的 Javascript】Day 20 - 閉包 (Closure) # Part 2
下一篇
【這些年我似是非懂的 Javascript】Day 22 - 是這個不是那個的 this # Part 2.
系列文
【這些年我似是非懂的 Javascript】34

尚未有邦友留言

立即登入留言