iT邦幫忙

2021 iThome 鐵人賽

DAY 10
0
自我挑戰組

登堂入室!前端工程師的觀念技術 _30_ 題系列 第 10

9. 關於 this 的 5 題練習

這篇只包含我自己不熟悉的題型,建議有看到文章的人自己做做看題目

題目來自 六角學院觀念測驗:JavaScript 熱門面試題
(目前題型是公開的,如果之後題目表單關閉,這篇文章會刪除。)

覺得自己對this沒概念的人可以先看這篇:淺談 JavaScript 頭號難題 this:絕對不完整,但保證好懂 - Huli

然後題目都是在browser執行!!用node執行大部分答案都會不一樣。

-----正文開始-----

  1. 請問 this 將會出現什麼答案?
function callName() {
    console.log(this.name); 
}
var auntie = {
    name: '漂亮阿姨',
    callName: callName,
    watch: {
        name: 'Magic Watch',
        callName: callName,
    }
}

var callName1 = auntie;                 
var callName2 = auntie.watch;           
var callName3 = callName1.callName();   
var callName4 = callName2.callName;     

 callName3;
 callName4;

題解

  • callName3 = callName1.callName() = auntie.callName()
    這裡的callName()函式宣告(Function Declaration) 的this,而函式宣告的this指向執行呼叫的物件。
    這裡執行呼叫的是auntie,所以 this = auntie。
    this.name = auntie.name : 漂亮阿姨

  • callName4 = callName2.callName,要注意的是: 這裡的callName並沒有呼叫"()"。 所以這裡的callName會回傳 整個callName的函式宣告 回來。

Ans. 漂亮阿姨 / function callName()

自主練習
如果是執行呼叫的話,把var callName4 = callName2.callName;改成:

var callName4 = callName2.callName(); 
  • callName4 = callName2.callName() = auntie.watch.callName()
    這裡的callName物件方法(object method) 的this,物件方法的this指向物件本身,這裡指的物件是auntie.watch,所以auntie.watch.callName() : Magic Watch
  1. 請問 this 將會出現什麼答案?
var name = '小明';
var obj = {
    x: () => {
        name = '小王';
        console.log(this.name);
    },
    y: '2',
}

obj.x(); 


題解

  • 在browser裡,var name的宣告會被放進browser的global物件 Window.name的屬性,let nameconst name則不會有影響。
  • obj.x();執行了兩個工作:
    1. 將變數name設為'小王': 這裡找到的name就是已經被設為'小明'的Window.name,所以現在的 Window.name 會從'小明'變成'小王'。
    2. console.log(this.name); : 這裡的this是**箭頭函式(Arrow functions)**的this,因為箭頭函式不擁有this,因此這裡的this是指window
      因此,this.name = Window.name = '小王'。

Ans. 小王
(在node.js裡執行,this會是Global,而this.name會變成undefined。)

  1. 請問 this 將會出現什麼答案?
var name = '小明';
var obj = {
    x: {
        name: '小虎',
        myname: function() {
            console.log(this.name);
            setTimeout(function() {  
                console.log(this.name);
            }, 500)
        }
    },
    y: '2',
    name: '小王',
}

var a = obj.x.myname(); 
a;
// in Browser: 小虎/ 小明
// node : 小虎/ undefined

題解

  • a = obj.x.myname();
    1. 這裡的第一個this.name是函式宣告的this,會指向呼叫函式的物件obj.x。所以this.name = obj.x.name = '小虎'。
      2. 第二個this.name被放在setTimeout裡面,由於setTimeout(),setInterval()等非同步呼叫的程式碼,運行在與其他函式不同的執行環境,抓取不到物件,所以this會指向window。所以 this.name = window.name = '小明'。

Ans. 小虎 / 小明

4.請問 this 將會出現什麼答案?

function callName(name){
    console.log(this.name, name); 
}
var name = '全域阿婆';
var auntie = {
    name: '漂亮阿姨',
}

callName(undefined, '小明');        
callName.call(auntie, '小明');      
  • console.log(this.name, name);是函式宣告的this,this會指向呼叫函式的物件。
    1. this.name: 這裡執行callName(undefined, '小明');的方式是 simple call,this指向的物件是window,所以 【this.name = window.name = '全域阿婆'。】
    2. name: function callName(name)裡的name會參考到傳入的參數,在這裡是 undefined
      至於參數的'小明'是多餘的參數,JS只是不會在有過多參數的時候報錯,但是會忽略他。
  • callName.call(auntie, '小明'); call()的第一個參數是指定呼叫函式的對象,第二個以後的參數會是預計傳入函式的參數。所以這個函式也可以看成 auntie.callName('小明')
    所以這裡可以很明顯的看出來,這裡的this = auntie
    1. this.name = auntie.name = '漂亮阿姨'
    2. name = undefined

Ans. 全域阿婆 / undefined,漂亮阿姨 / 小明

  1. 請問 this 將會出現什麼答案?
var name = '全域';
var auntie = {
    name: '漂亮阿姨',
    callName: function() {
        console.log(this.name); 
    }
};
(function(){
    var a = auntie.callName;
    a();
})();

題解

  • 最大的前提還是function是函式宣告,this指向呼叫韓式的物件。
  • var a = auntie.callName這裡要注意callName沒有被呼叫"()",所以這裡可以看成**a是一個會執行console.log(this.name)的function。**
  • a()執行的Simple call,所以a()的this指向的是window
    因此 this.name = window.name = '全域'

Ans. 全域

比較

var name = '全域';
var auntie = {
    name: '漂亮阿姨',
    callName: function() {
        console.log(this.name);  //auntie.name = "漂亮阿姨"
    }
};
(function(){
    var a = auntie.callName();
    a;
})();

相較於上面的例子, auntie.callName()代表呼叫callName的物件是auntie,所以這裡的this也指向auntie。
所以當輸入a;時,這裡回傳的會是auntie.callName()。
this.name = auntie.name = '漂亮阿姨'。

【如內文有誤還請不吝告知>< 謝謝閱覽至此的各位:D】

-----正文結束-----

考慮了很久要不要寫this的文章,但我覺得還是做題目最容易理解。
因為都是寫給我自己的,所以這篇可能對社會特別沒貢獻QQ。但我有盡量把專有名詞寫出來,即使看不懂,查起資料來應該也比較方便。


上一篇
8. 解釋 Event Loop ( 下 ) --- Task Queue ( Callback Queue )
下一篇
10. 解釋 AJAX 的工作原理(XMLHttpRequest)
系列文
登堂入室!前端工程師的觀念技術 _30_ 題31

尚未有邦友留言

立即登入留言