Try   HackMD

this 到底是誰|筆記 by Sz

tags: Sz 課前 Vue新手夏令營
  • 主流框架都會用到
  • 是 function 隱藏版參數們
  • this 的特性
    • 主要看的就是 function 是從哪裡呼叫的,就是指誰
  • this 的幾種狀況
    • simple call (不太會這樣用)
    • object 的 function(最常用)
    • function 跟 iphone 一樣,你的 iphone 不是他的 iphone
    • 陷阱題
      • object 中還有 object
      • Object 裡面的 function 硬要呼叫全域 function
      • callback function

function 的隱藏版參數們

這是一個 function,參數除了我們自己定義的 parameter 之外(範例中為 params)
還有其他 function 內建的參數

  • this
  • window
  • arguments
var a = '全域'
function fn(params) {
  console.log(params, this, window, arguments);
  debugger;
}

他們可以在哪裡看到呢?

debugger

會將 Devtool 的 debugger 停在這個程式碼上

scope 作用域

在 scope 裡可以看到這些隱藏版參數,執行剛剛的 fn()

fn(1, 2, 3);   // 觀察執行 function 後
  • fn
    • <this>: Window
    • arguments: 多了一個類陣列 (1, 2, 3)
  • Window: Global

this 的特性

  • 指向是會變動的
  • 不用太煩惱,通常只會用到一種
  • 傳統的 function 的 this 只與調用方式有關,跟定義沒什麼關係(新的 function 看箭頭函式那篇)
  • 主要看的就是 function 是從哪裡呼叫的,就是指誰

this 的幾種狀況

開始把這個 function 想成一台 iphone

不太會這樣用:simple call

function 在全域中,function 中的 this 指向全域
這台 iphone 還在 apple 商店裡,他沒有主人

var someone = '全域';
function callSomeone() {
  // 呼叫全域的變數:simple call
  console.log(this.someone);  
}
callSomeone();

最常用的:object 裡的 function

function 在 object 中,function 中的 this 指向 object
這台 iphone 還在 apple 商店裡,他沒有主人
有 object 的 iphone 就有主人了,他的主人是 obj

var obj = {
  someone: '物件',
  callSomeone() {
    console.log(this.someone);
  }
}
obj.callSomeone();

看 function 是誰的,this 就是指誰

不同個 object 擁有同個 function 並不衝突,就像你有 iphone,他也可以有

var obj2 = {
  someone: '物件2',
  callSomeone()      // 語法糖省略 key
}
obj2.callSomeone();  // 指向 obj2

陷阱題

Object 中還有 Object

小孩的 iphone 不是你的 iphone

var wrapObj = {
  someone: '外層物件',
  callSomeone(),          // wrapObj 的 function
  innerObj: {
    someone: '內層物件',
    callSomeone(),        // innerObj 的 function
  }
}
wrapObj.innerObj.callSomeone();

Object 裡面的 function 硬要呼叫全域 function

callSomeone 還是全域的 funciton

var obj3 = {
  someone: '物件 3',
  fn() {
    callSomeone(); // 通常平常不會這樣去取用 this
  }
}
obj3.fn();

callback function:避免用 this

使用 callback function(像是在forEach裡),大部分就是把一個定義好的 function 簡化放到 callback funciton 裡面
所以他還是一個全域的 function

var obj4 = {
  someone: '物件 4',
  fn() {
    setTimeout(function () {
      console.log(this.someone);    // simple call
    });
  }
}
obj4.fn();