call,apply和bind的小小總結

在前端面試時候經常會問apply,call有什麼區別,平時會用他們做什麼。
對於這個問題,已經有很多文章介紹了,我這裏就不進行太過複雜的說明,就簡單總結一下他們的區別,然後介紹一個很好玩的例子供大家理解。
開始正文:

第一章 call,apply和bind的概念

1.1 call

call() 方法使用一個指定的 this 值和單獨給出的一個或多個參數來調用一個函數。
注意:call接受的是一個參數列表

1.1.1 語法

function.call(thisArg, arg1, arg2, ...)

thisArg可選的。在 function 函數運行時this指向的對象。如果這個函數處於非嚴格模式下,當thisArg指定爲 null 或 undefined 時會自動替換爲指向全局對象。

arg1,arg2:參數列表

1.1.2 返回值

使用調用者提供的 this 值和參數列表調用該函數的返回值。若該方法沒有返回值,則返回 undefined。

注意:使用call會執行該函數,如果有返回值,則返回該值;如果沒有返回值,返回Undefined

1.1.3 作用

  1. 在一個子構造函數中,可以通過調用父構造函數的 call 方法來實現繼承
  2. 使用 call 方法調用匿名函數
  3. 使用 call 方法調用函數並且指定上下文的 ‘this’

1.2 apply的概念

apply() 方法調用一個具有給定this值的函數,以及作爲一個數組(或類似數組對象)提供的參數。
注意:apply接收的參數是參數數組

1.2.1 語法

func.apply(thisArg, [argsArray])

thisArg必選的。在 function 函數運行時使用的 this 值。如果這個函數處於非嚴格模式下,當thisArg指定爲 null 或 undefined 時會自動替換爲指向全局對象。

(和call區別就是thisArg是必選的,其他都和call相同)

argsArray:一個數組或者類數組對象,其中的數組元素將作爲單獨的參數傳給 func 函數。
另外也可以使用 arguments對象作爲 argsArray 參數(arguments 是一個函數的局部變量)。 它可以用作被調用對象的所有未指定的參數 。 這樣,在使用apply函數的時候就不需要知道被調用對象的所有參數。 可以使用arguments來把所有的參數傳遞給被調用對象。 被調用對象接下來就負責處理這些參數。

1.2.2 返回值

調用有指定this值和參數的函數的結果。

1.2.3 作用

  1. 用 apply 將數組添加到另一個數組
var array = ['a', 'b'];
var elements = [0, 1, 2];
array.push.apply(array, elements);
console.log(array); // ["a", "b", 0, 1, 2]
  1. 使用apply來鏈接構造器

1.3 bind的概念

bind() 方法創建一個新的函數,在 bind() 被調用時,這個新函數的 this 被指定爲 bind() 的第一個參數,而其餘參數將作爲新函數的參數,供調用時使用。

1.3.1 語法

function.bind(thisArg[, arg1[, arg2[, ...]]])

thisArg:調用綁定函數時作爲 this 參數傳遞給目標函數的值。 如果 bind 函數的參數列表爲空,或者thisArg是null或undefined,執行作用域的 this 將被視爲新函數的 thisArg。
arg1, arg2:當目標函數被調用時,被預置入綁定函數的參數列表中的參數

1.3.2 返回值

返回一個原函數的拷貝,並擁有指定的 this 值和初始參數。
注意:這裏不像call和apply一樣返回函數結果,而是返回函數的Copy

1.3.3 作用

  1. 創建綁定函數
    bind() 最簡單的用法是創建一個函數,不論怎麼調用,這個函數都有同樣的 this 值。
  2. 設置初始參數
    bind() 的另一個最簡單的用法是使一個函數擁有預設的初始參數。只要將這些參數作爲 bind() 的參數寫在 this 後面。當綁定函數被調用時,這些參數會被插入到目標函數的參數列表的開始位置,傳遞給綁定函數的參數會跟在它們後面。
  3. 配合 setTimeout

第二章 例子

通過上面的介紹,再看一個例子

const person = { name: 'Lydia' };

function sayHi(age) {
  return `${this.name} is ${age}`;
}

console.log(sayHi.call(person, 21));
console.log(sayHi.bind(person, 21));

結果是什麼呢?

答案:
Lydia is 21
[Function: bound sayHi]

原因:callbind都可以將object傳遞給this指向的內容,也就是可以將person21傳遞給sayHi
但是,call是立即執行,返回函數執行結果,而bind不會立即執行,是返回函數,但具有綁定的上下文!
所以想要bind生效,可以這麼使用

const person = { name: 'Lydia' };

function sayHi(age) {
  return `${this.name} is ${age}`;
}

console.log(sayHi.bind(person, 21)());
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章