轉載自 這理
前言 :
在 JavaScript 中,函式是物件,是 Function 的實例,可以在變數間任意指定,可以傳給函式的參數參考,當然,要新增為物件的特性也是可以的。例如 :
在上例中定義了一個 toString() 函式,並分別設定為 p1 與 p2 的 toString 來參考,透過 p1, p2 呼叫時,toString() 就像是 p1, p2 的方法(Method).
this 是什麼 :
在上例中,toString() 函式中使用了this,在呼叫函式時,每個函式都會有個 this,然而 this 參考至哪個物件,其實依呼叫方式而有所不同。以上例而言,透過 p1 呼叫時,toString() 中的 this 會參考至 p1 所參考的物件,也因此顯示 p1 物件的 name 與 age 值,透過 p2 呼叫時,toString() 中的 this 則會參考至 p2 所參考的物件. 如果呼叫函式時是透過物件與點運算子的方式呼叫,則 this 會參考至點運算子左邊的物件. 在 JavaScript 中,函式是 Function 的實例,Function 都會有個 call() 方法,可以讓你決定 this 的參考對象. 舉例來說,你可以如下呼叫 :
這次並沒有將 toString 指定為物件的特性,而是直接使用 call() 方法來呼叫函式,call() 方法的第一個參數就是用來指定函式中的 this 所參考的物件。如果函式原本具有參數,則可接續在第一個參數之後. 例如 :
Function 也有個 apply() 方法,作用與 call() 方法相同,也可讓你在第一個參數指定 this 所參考的對象,不過 apply() 方法指定後續引數時,必須將引數收集為一個陣列,如果你有一組引數,必須在多次呼叫時共用,就可以使用 apply() 方法. 例如 :
所以,this 實際參考的對象,是以呼叫方式而定,而不是它是否附屬在哪個物件而定. 例如就算函式是附屬在函式上的某個特性,也可以這麼改變 this 所參考的對象 :
在最後一個測試中,是以 p1.toString.call(p2) 的呼叫方式,所以雖然 toString() 是 p1 的特性,但 call() 指定 this 是參考至 p2,結果當然也是傳回 p2 的 name.
在用物件實字建立物件時,也可以直接指定函式作為特性. 例如 :
由於頂層函式是全域物件上的特性,所以作為一個頂層函式呼叫時,this 會參考至全域. 例如 :
當一個內部函式直接被呼叫時,this 也是參考至全域物件. 例如 :
在上例中,最後一個例子雖然指定外部函式的 this 為 o1,但事實上,內部函式被呼叫時,this 仍是參考至全域物件. 如果是以下這個例子 :
JavaScript 執行過程中,搞清楚 this 是誰有時非常重要,this 的決定方式是在於呼叫,而非定義的方式! 舉個例子來說,如果你想要自行實現 Array 的 forEach 方法,則可以如下 :
在上例中,由於呼叫 forEach 時,obj 參考的物件就是 this 所參考的物件,因而可以取得 length 等特性,函式是物件,所以自然可以丟給 forEach 作為引數,這也就是 陣列 中介紹到 Array上 forEach 方法的實作原理.
前言 :
在 JavaScript 中,函式是物件,是 Function 的實例,可以在變數間任意指定,可以傳給函式的參數參考,當然,要新增為物件的特性也是可以的。例如 :
在上例中定義了一個 toString() 函式,並分別設定為 p1 與 p2 的 toString 來參考,透過 p1, p2 呼叫時,toString() 就像是 p1, p2 的方法(Method).
this 是什麼 :
在上例中,toString() 函式中使用了this,在呼叫函式時,每個函式都會有個 this,然而 this 參考至哪個物件,其實依呼叫方式而有所不同。以上例而言,透過 p1 呼叫時,toString() 中的 this 會參考至 p1 所參考的物件,也因此顯示 p1 物件的 name 與 age 值,透過 p2 呼叫時,toString() 中的 this 則會參考至 p2 所參考的物件. 如果呼叫函式時是透過物件與點運算子的方式呼叫,則 this 會參考至點運算子左邊的物件. 在 JavaScript 中,函式是 Function 的實例,Function 都會有個 call() 方法,可以讓你決定 this 的參考對象. 舉例來說,你可以如下呼叫 :
這次並沒有將 toString 指定為物件的特性,而是直接使用 call() 方法來呼叫函式,call() 方法的第一個參數就是用來指定函式中的 this 所參考的物件。如果函式原本具有參數,則可接續在第一個參數之後. 例如 :
Function 也有個 apply() 方法,作用與 call() 方法相同,也可讓你在第一個參數指定 this 所參考的對象,不過 apply() 方法指定後續引數時,必須將引數收集為一個陣列,如果你有一組引數,必須在多次呼叫時共用,就可以使用 apply() 方法. 例如 :
所以,this 實際參考的對象,是以呼叫方式而定,而不是它是否附屬在哪個物件而定. 例如就算函式是附屬在函式上的某個特性,也可以這麼改變 this 所參考的對象 :
在最後一個測試中,是以 p1.toString.call(p2) 的呼叫方式,所以雖然 toString() 是 p1 的特性,但 call() 指定 this 是參考至 p2,結果當然也是傳回 p2 的 name.
在用物件實字建立物件時,也可以直接指定函式作為特性. 例如 :
由於頂層函式是全域物件上的特性,所以作為一個頂層函式呼叫時,this 會參考至全域. 例如 :
當一個內部函式直接被呼叫時,this 也是參考至全域物件. 例如 :
在上例中,最後一個例子雖然指定外部函式的 this 為 o1,但事實上,內部函式被呼叫時,this 仍是參考至全域物件. 如果是以下這個例子 :
JavaScript 執行過程中,搞清楚 this 是誰有時非常重要,this 的決定方式是在於呼叫,而非定義的方式! 舉個例子來說,如果你想要自行實現 Array 的 forEach 方法,則可以如下 :
在上例中,由於呼叫 forEach 時,obj 參考的物件就是 this 所參考的物件,因而可以取得 length 等特性,函式是物件,所以自然可以丟給 forEach 作為引數,這也就是 陣列 中介紹到 Array上 forEach 方法的實作原理.
This message was edited 16 times. Last update was at 26/12/2017 13:51:09
沒有留言:
張貼留言