欣迪

在 JavaScript 中,this 是一個關鍵字,它的值在運行時被綁定。this 的值可能在不同的上下文中有所不同。 當 this 被放在 object 裡面的 function 裏面,那麼 this 就指向該 object (箭頭函數除外)。

所以當一般直接定義的 function 的 this 就是指向最外層的全局對象( 也是一個 object ),瀏覽器是 window,node 環境是 global。

Part 1. 請寫出問號分別會 console.log 什麼?

const obj = {
  name: 'Heisenberg',
  sayMyName: function () {
    console.log(this.name)
  }
}

obj.sayMyName() // 答案1 ??

setTimeout(() => {
  obj.sayMyName() // 答案2 ??
}, 1000)


setTimeout(obj.sayMyName, 1000) // 答案3 ??

答案1 , 2 => ‘Heisenberg’
答案 3 => ”

答案1. 和 答案 2. 毫無疑問指向 obj , 所以是 ‘Heisenberg’。

答案3. 就有點意思了。當他被做為參數給 setTimeout 使用時,你可以想像它已經是一個獨立的 function 被當 callback 傳入,簡化的範例如下:

const obj = {
  name: 'Heisenberg',
  sayMyName: function () {
    console.log(this.name)
  }
}

function test(callback) {
	callback()
}

test(obj.sayMyName)
  

這樣的情況下,this 當然指向全局對象,所以答案3會返回 window.name 或 global.name 。

Part 2. 請寫出問號分別會 console.log 什麼?

const obj = {
  name: 'Heisenberg',
  hello() {
    console.log('Hello, ' + this.name)
  },
  goodbye: () => {
    console.log('Goodbye, ' + this.name)
  }
}

obj.hello() // 答案4 ??

obj.goodbye() // 答案5 ??

這邊比較基本。就是考箭頭函數的特性: 如果在當前範圍中搜索不到 this 變量時,他們最終會尋找其封閉範圍。

答案4 ‘Hello, Heisenberg’

答案5 ‘Goodbye, ‘ + (window.name)

Part 3. 請寫出問號分別會 console.log 什麼?

var length = 5

function callBack() {
  console.log(this.length)
}

const obj_1 = {
  length: 4,
  method(callback) {
    callback() 
  }
}

obj_1.method(callBack, 2, 3) // 答案6 ??

const obj_2 = {
  length: 4,
  method() {
    arguments[0]()
  }
}

obj_2.method(callBack, 2, 3)  // 答案7 ??

答案 6 => 5
答案 7 => 3

答案 6. 這題和 答案3. 的狀態相反。 當 function 被當參數傳送進去時,當成一個新定義的 function。BUT 函數本身並不是 object 包含在 property 定義中,所以還是導向 wiondow 回傳 5。
如果改成以下又不一樣了:

var length = 5

function callBack() {
  console.log(this.length)
}

const obj_1 = {
  length: 4,
  method(callback) {
    this.callback = callback
    this.callback() 
  }
}

obj_1.method(callBack, 2, 3) // 回傳 4

答案7. obj_2 使用 arguments 取得參數。 所以 arguments 相當於 [callback, 2, 3]。 我們看一下 js 中 array 和 object 的關聯:

JavaScript 中的類型分為七種:undefined、null、boolean、number、string、symbol 和 object。對於所有非基本類型的值(即對象),typeof 運算符的返回值都是“object”。

array 是 JavaScript 中的一種特殊類型的對象,它可以用來存儲一組有順序的值。數組中的每個值都有一個查詢,可以通過查詢引用來訪問數組中。

簡單的說,array 就是用數字當索引的 object,所以這邊 答案7 的 this 指向 arguments,而 arguments.length 等於 3 。

總結一下解題技巧

不是由 object property 定義的 function 一律指向最外層 (window, global ),當 object.fn 被當作參數傳遞時,則與 object 脫鉤,可以視為一個獨立定義的函數。

各位都答對了嗎?

訂閱 IT-Monk

訂閱最新文章的發布消息! 😚😚😚
Loading

作者介紹 - 欣迪

欣迪

從設計到寫程式,發現自己有追求前端技巧的自虐傾向。不斷的踩坑,再從坑裡爬出來,慢慢對攀岩有點心得。 目前在多間公司擔任網站設計顧問。 同時也是網站架設公司負責人。