this 決定在於函式如何被呼叫
以下為各個案例
1.變數指定物件下的方法,並執行
 var name = 'GlobalName';
   function foo() {
     console.log(this.name);
   }
   var obj = {
     name: 'tom',
     foo: foo,
   };
   obj.foo()                        //tom(物件的方法調用)
   var callThisName = obj.foo;      //GlobalName(間接參考)
   callThisName(); // "GlobalName"
2.參數傳遞中的callback function,也屬於間接參考
var name = 'GlobalName';
function foo() {
  console.log(this.name);
}
var obj = {
  name: 'tom',
  foo: foo,
};
function boo(fn) {
  fn();
}
boo(obj.foo); // "GlobalName"
3.物件下的多層方法也屬於間接參考
var name = 'GlobalName';
var obj = {
  name: 'tom',
  foo: function(){
    console.log(this.name)         //tom
    function inner() {
      console.log(this.name)       //GlobalName
      function inner2() {
        console.log(this.name)     //GlobalName
      }   
       inner2()
    }
    inner()
  }
};
obj.foo()
1.依序出現甚麼
function callName(){
  console.log(this.name)
}
var obj = {
  name:'tom',
  callName:callName,
  nickname:{
    name:'tommy',
    callName:callName
  }
}
obj.callName()
obj.nickname.callName()
Ans: tom、tommy
2.依序出現甚麼
var name = "Global name"
function callName(){
  console.log(this.name)
}
var obj = {
  name:'tom',
  callName:callName,
  nickname:{
    name:'tommy',
    callName:callName
  }
}
var newcall1 = obj.callName
var newcall2 = obj.nickname.callName
newcall1()
newcall2()
Ans: Global name、Global name(因為是間接參考)
3.依序出現甚麼
function callName(){
  console.log(this.name)
}
var obj = {
  name:'tom',
  callName:callName,
  nickname:{
    name:'tommy',
    callName:callName
  }
}
var newcall1 = obj
var newcall2 = obj.nickname
var newcall3 = newcall1.callName()      //已執行,非間接參考
var newcall4 = newcall2.callName
newcall3
newcall4
Ans:tom、[Function: callName]
4.會印出什麼呢~若是嚴謹模式下又會印出甚麼
// "use strict"
var name = 'tom';
function callName(){
  console.log(this.name);
};
var a = {
  name:'alice',
  callName:callName
}
callName.name = 'jonna'
a.callName()
Ans:alice、Cannot assign to read only property 'name'
5.會依序印出什麼呢~(時常忘記!!)
var name = 'tom';
var a = {
  name:'alice',
  myName:function () {
    console.log(this.name);
    let call = () =>{
    console.log(this.name);
    }
    call()
  },
 call2:() =>{
    console.log(this.name);
  },
  call3:()=>{
    name = 'wtf?'
    console.log(this.name)
  },
}
a.myName();
a.call2();
a.call3()
Ans: alice、alice、tom、wtf? (箭頭函式作用域)
6.會依序印出什麼呢~(開始覺得噁心了....)
var name = 'tom';
var obj = {
  x:{
    name:'jam',
    myname:function(){
      console.log(this.name);
      (function(){
        console.log(this.name);
      })();
      setTimeout(function(){
        console.log(this.name);
      },500)
    }
  },
  name:'alice'
}
var a = obj.x.myname();
a;
Ans:jam、tom、tom
7.依序出現什麼答案(噁心更加延伸)
var name = 'tom';
var obj = {
  x:{
    name:'jam',
    myname:function(){
      this.name = 'amy'
      console.log(this.name);
      (function(){
        this.name = 'john'
        console.log(this.name);
      })();
      function final(){
        console.log(this.name)
      };
      setTimeout(function(){
        this.name = 'sam'
        console.log(this.name);
        final()
      },500);
    }
  },
  name:'alice'
}
var a = obj.x.myname();
a;
console.log(obj.x.name)
console.log(this.name)
Ans:amy、john、amy、john、sam、john
參考資源:
竹白筆記、影片、文章、js熱門面試題