這篇只包含我自己不熟悉的題型,建議有看到文章的人自己做做看題目!
題目來自 六角學院 的 觀念測驗:JavaScript 熱門面試題。
(目前題型是公開的,如果之後題目表單關閉,這篇文章會刪除。)
覺得自己對this沒概念的人可以先看這篇:淺談 JavaScript 頭號難題 this:絕對不完整,但保證好懂 - Huli
然後題目都是在browser執行!!用node執行大部分答案都會不一樣。
-----正文開始-----
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 Watchvar name = '小明';
var obj = {
x: () => {
name = '小王';
console.log(this.name);
},
y: '2',
}
obj.x();
題解
var name
的宣告會被放進browser的global物件 Window.name
的屬性,let name
和const name
則不會有影響。obj.x();
執行了兩個工作:
Window.name
,所以現在的 Window.name
會從'小明'變成'小王'。console.log(this.name);
: 這裡的this是**箭頭函式(Arrow functions)**的this,因為箭頭函式不擁有this,因此這裡的this是指window
。this.name
= Window.name
= '小王'。Ans. 小王
(在node.js裡執行,this會是Global,而this.name會變成undefined。)
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();
this.name
是函式宣告的this,會指向呼叫函式的物件obj.x
。所以this.name
= obj.x.name
= '小虎'。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會指向呼叫函式的物件。
this.name
: 這裡執行callName(undefined, '小明');
的方式是 simple call,this指向的物件是window
,所以 【this.name
= window.name
= '全域阿婆'
。】name
: function callName(name)裡的name
會參考到傳入的參數,在這裡是 undefined
。callName.call(auntie, '小明');
call()的第一個參數是指定呼叫函式的對象,第二個以後的參數會是預計傳入函式的參數。所以這個函式也可以看成 auntie.callName('小明')
。auntie
。
this.name
= auntie.name
= '漂亮阿姨'
】name
= undefined
】Ans. 全域阿婆 / undefined,漂亮阿姨 / 小明
var name = '全域';
var auntie = {
name: '漂亮阿姨',
callName: function() {
console.log(this.name);
}
};
(function(){
var a = auntie.callName;
a();
})();
題解
var a = auntie.callName
這裡要注意callName沒有被呼叫"()",所以這裡可以看成**a
是一個會執行console.log(this.name)
的function。**a()
執行的Simple call,所以a()的this指向的是window
。'全域'
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。但我有盡量把專有名詞寫出來,即使看不懂,查起資料來應該也比較方便。