1. 程式人生 > 其它 >apply()、call()、bind()

apply()、call()、bind()

技術標籤:js基礎js

這兩個方法都會以指定的 this 值來呼叫函式,即會設定呼叫函式時函式體內 this 物件的值。

  1. apply()方法
    接收的引數:
    函式內 this 的值和一個引數陣列。第二個引數可以是 Array 的例項,但也可以是 arguments 物件。
function sum(num1, num2) { 
 return num1 + num2; 
} 
function callSum1(num1, num2) { 
 return sum.apply(this, arguments); // 傳入 arguments 物件
} 

function callSum2
(num1, num2) { return sum.apply(this, [num1, num2]); // 傳入陣列 } console.log(callSum1(10, 10)); // 20 console.log(callSum2(10, 10)); // 20

在這個例子中,callSum1()會呼叫 sum()函式,將 this 作為函式體內的 this 值(這裡等於window,因為是在全域性作用域中呼叫的)傳入,同時還傳入了 arguments 物件。callSum2()也會呼叫 sum()函式,但會傳入引數的陣列。這兩個函式都會執行並返回正確的結果。

  1. call()方法
    call()方法與 apply()的作用一樣,只是傳參的形式不同。

    接收的引數:第一個引數跟 apply()一樣,也是 this值,而剩下的要傳給被呼叫函式的引數則是逐個傳遞的。換句話說,通過 call()向函式傳參時,必須將引數一個一個地列出來。
function sum(num1, num2) { 
 return num1 + num2; 
} 
function callSum(num1, num2) { 
return sum.call(this, num1, num2); 
} 
console.log(callSum(10, 10)); // 20

這裡的 callSum()函式必須逐個地把引數傳給 call()方法。結果跟 apply()的例子一樣。到底是使用 apply()還是 call(),完全取決於怎麼給要呼叫的函式傳參更方便。如果想直接傳 arguments物件或者一個數組,那就用apply();否則,就用 call()。當然,如果不用給被呼叫的函式傳參,則使用哪個方法都一樣。

注意:call和apply的第一個引數是null/undefined時函式內的的this指向window或global
有兩種情況需要注意,傳null或undefined時,將是JS執行環境的全域性變數。瀏覽器中是window,其它環境(如node)則是global。

  1. apply()和 call()真正強大的地方並不是給函式傳參,而是控制函式呼叫上下文即函式體內 this值的能力。
window.color = 'red'; 
let o = { 
 color: 'blue' 
}; 
function sayColor() { 
 console.log(this.color); 
} 
sayColor(); // red 
sayColor.call(this); // red 
sayColor.call(window); // red 
sayColor.call(o); // blue

這個例子是在之前那個關於 this 物件的例子基礎上修改而成的。同樣,sayColor()是一個全域性函式,如果在全域性作用域中呼叫它,那麼會顯示"red"。這是因為 this.color 會求值為 window.color。如果在全域性作用域中顯式呼叫 sayColor.call(this)或者sayColor.call(window),則同樣都會顯示"red"。而在使用 sayColor.call(o)把函式的執行上下文即 this 切換為物件 o 之後,結果就變成了顯示"blue"了。

  1. bind()
    bind()方法會建立一個新的函式例項,其 this 值會被繫結到傳給 bind()的物件。
window.color = 'red'; 
var o = { 
 color: 'blue' 
}; 
function sayColor() { 
 console.log(this.color); 
} 
let objectSayColor = sayColor.bind(o); 
objectSayColor(); // blue

這裡,在 sayColor()上呼叫 bind()並傳入物件 o 建立了一個新函式 objectSayColor()。
objectSayColor()中的 this 值被設定為 o,因此直接呼叫這個函式,即使是在全域性作用域中呼叫,也會返回字串"blue"。

相關題目:
下面求a中最大值正確的是

var a = [1,4,5,2,9];
A. Math.max(a)
B. Array.max(a)
C. Math.max.call(null,a)
D. Math.max.apply(null,a)

答案: D
解析:
Math物件包含max()方法,用於確認一組數值中的最大值。該方法接收任意多個數值引數,不接受陣列引數。
call( )需要傳遞明確幾個引數,接受的是一個引數列表。
apply( )需要兩個引數,第一個可以任意,第二個可以接收一個數組作為引數,不管陣列中有多少個元素。