克服JS奇怪的部分_call()、apply() 與 bind()

Huang Pei
Huang Pei
Nov 6 · 6 min read

call/ apply/ bind/ 函數借用 (function borrowing)/ 柯里化 (Function Curring)

本筆記出自:JavaScript 全攻略:克服 JS 的奇怪部分


call, apply, bind 是函數物件中設定 this 關鍵字的內建方法。

apply 和 call 呼叫函數,然後讓你設定this接著傳入其他參數。bind則創造函數的拷貝,讓你設定this關鍵字,還可以讓你設定預設參數,不會變的預設參數。

函式具有程式碼(可被呼叫)+名稱,並因為是物件,底下有call, apply,bind方法可被調用

  • bind() 方法會建立一個新函式。該函式被呼叫時,會將 this 關鍵字設為給定的參數,並在呼叫時,帶有提供之前,給定順序的參數。
var person = {
firstName: “john”,
lastName: “Doe”,
getFullName() {
var fullName = this.firstName + “ “ + this.lastName;
return fullName;}
};
//原本的logName綁定person
var logName = function(lang1, lang2) {
console.log(“Logged:” + this.getFullName())}
.bind(person); // Logged:john Doe
//建立一拷貝logName並綁定person的logPersonName函式
var
logPersonName = logName.bind(person); // Logged:john Doe
logPersonName();
logName()

  • call()使用給定的this參數以及分別給定的參數來呼叫某個函數
var person = {
firstName: “john”,
lastName: “Doe”,
getFullName() {
var fullName = this.firstName + “ “ + this.lastName;
return fullName;}
};
var logName = function(lang1, lang2) {
console.log(“Logged: ” + this.getFullName());
console.log(“Arguments: ” + lang1 + ' ' + lang2 );}
logName.call(person, 'en', 'es')
//
Logged: john Doe
//Arguments: en es

不像bind會創造函數的拷貝,call會真的執行函數,傳入call的第一個參數是this要指向的東西(person),剩下的是想要傳給函數的參數(en, es)。

經常運用於柯里化。


  • apply()方法會呼叫一個以 this 的代表值和一個陣列形式的值組(或是一個 array-like object )為參數的函式。
var person = {
firstName: “john”,
lastName: “Doe”,
getFullName() {
var fullName = this.firstName + “ “ + this.lastName;
return fullName;}
};
var logName = function(lang1, lang2) {
console.log(“Logged: ” + this.getFullName());
console.log(“Arguments: ” + lang1 + ' ' + lang2 );}
logName.apply(person, ['en', 'es']) //第二個參數是陣列
//
Logged: john Doe
//Arguments: en es

基本上用法和call差不多,只是第二個參數必是陣列形式。

使用立即函式的手法呼叫:(function(lang1, lang2) {
console.log(“Logged: “ + this.getFullName());
console.log(“Arguments: “ + lang1 + “ “ + lang2);}
).apply(person, [“en”, “es”]);

使用時機:

  1. 函數借用 (function borrowing)
var person = {
firstName: “john”,
lastName: “Doe”,
getFullName() {
var fullName = this.firstName + “ “ + this.lastName;
return fullName;}
};
// person2沒有getFullName的方法,但想要使用的話,可以和person借var person2 = {
firstName: “Jane”,
lastName: “Doe”,
};
person.getFullName.call(person2) // Jane Doe

2. bind的柯里化運用 (Function Curring)

Function Curring

Generating a copy of a function but with some preset parameters.

Very useful in mathematical situations.

柯里化:將一個接收複數參數的函式轉為一連串接收單一參數的函式。

bind 建立一個函數的拷貝,並設定預設的參數,在數學運算之下很有用。

function multiply(a, b) {
return a * b; }
* 傳入的this忽略不用管,而bind的this後面傳的參數類似預設值// 固定參數 a 為 2,可傳入任意b
var multipleByTwo = multiply.bind(this,2);
multipleByTwo(4) //8
// 固定參數 a 為 2 , b 為 2 ,後續傳入的參數則沒有用
var multipleByTwo=multiply.bind(this,2,2)//4
multipleByTwo(4) //因為前面已經傳了參數,這裡傳什麼都沒差
// 沒有傳入固定的參數,a,b 就不會受限制
var multipleByTwo=multiply.bind(this)
multipleByTwo(5,2) //10
Huang Pei

Written by

Huang Pei

記錄用倉庫,歡迎指正。想成為前端工程師的少女。

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade