JavaScriptにおけるcall、apply、bindメソッドの理解
原題: Understanding call, apply and bind methods in Javascript
分析結果
- カテゴリ
- 不動産
- 重要度
- 49
- トレンドスコア
- 11
- 要約
- JavaScriptのcall、apply、bindメソッドは、関数の呼び出し時にthisの値を設定するための重要な機能です。callメソッドは、指定したthis値と引数を使って関数を呼び出します。applyメソッドも同様ですが、引数を配列として渡します。一方、bindメソッドは新しい関数を返し、thisの値を固定します。これらのメソッドを理解することで、より柔軟で効果的な関数の操作が可能になります。
- キーワード
Three little methods. One big idea: you control what this points to. Every time you write a function in JavaScript, there's a hidden element — the this keyword. Usually, it works fine, but when you extract a method or pass it as an event listener, this can point somewhere unexpected, causing confusing bugs. call , apply , and bind are the tools that help manage that hidden element. Let's explore with an example involving a bus company 🚌. The Example Setup Consider Purbasha Paribahan , a local bus company modeled as an object with a book method to record passenger reservations. const purbasha = { busName : ' Purbasha Paribahan ' , busCode : ' PB ' , bookings : [], book : function ( busNum , passengerName ) { console . log ( ` ${ passengerName } has booked a seat on ${ this . busName } with bus ${ this . busCode }${ busNum } .` ); this . bookings . push ({ bus : ` ${ this . busCode }${ busNum } ` , passengerName }); } }; Calling the function normally works perfectly: purbasha . book ( 12 , ' Sumon ' ); Output: Sumon has booked a seat on Purbasha Paribahan with bus PB12. Inside book , this refers to purbasha — exactly as intended. But things get interesting when a rival enters the scene. A competing company, Royal Express , needs similar booking functionality. Repeating the method isn't ideal, so we introduce our three heroes. const royal = { busName : ' Royal Express ' , busCode : ' RE ' , bookings : [] }; Method 1: call — Invoke Immediately with Arguments as a List First, get the book function separately, then use .call() to invoke it with this set to the desired object, passing arguments individually. const book = purbasha . book ; // separate function reference book . call ( royal , 45 , ' Tanvir ' ); Output: Tanvir has booked a seat on Royal Express with bus RE45. What's happening? call runs book immediately, manually setting this to royal . It's like: "Use this function but treat it as if it belongs to royal ". Argument Description 1st Object to assign this 2nd, 3rd, ... Function arguments Method 2: apply — Same as call , Arguments in an Array apply is similar but takes arguments as an array, useful when data is already in an array. const passengerData = [ 23 , ' Mahfuz ' ]; book . apply ( purbasha , passengerData ); Output: Mahfuz has booked a seat on Purbasha Paribahan with bus PB23. Tip: With ES6+, you can use the spread operator with call instead: book.call(purbasha, ...passengerData); Method Argument Passing call Individually listed apply In an array Method 3: bind — Create a New Function with this Set bind doesn't run the function immediately. Instead, it returns a new function with this permanently set, which you can call later. const bookRE = book . bind ( royal ); // new function bookRE ( 56 , ' Mustak ' ); // call the new function Output: Mustak has booked a seat on Royal Express with bus RE56. Using bind for Partial Application bind is especially useful for partial application, where you preset some arguments. // preset `this` and bus number 56 const bookRE56 = book . bind ( royal , 56 ); bookRE56 ( ' Robin ' ); bookRE56 ( ' Rafi ' ); Output: Robin has booked a seat on Royal Express with bus RE56. Rafi has booked a seat on Royal Express with bus RE56. Note: Partial application is creating specialized functions by presetting some arguments. Common Pitfall: Event Callbacks Using object methods as event handlers often causes this to break. Here's an example: purbasha . buses = 100 ; purbasha . buyBus = function () { this . buses ++ ; console . log ( this . buses ); }; // ❌ Wrong — don't do this document . querySelector ( ' .buy ' ) . addEventListener ( ' click ' , purbasha . buyBus ); Click, and you'll see NaN , not 101 . That's because in event callbacks, this refers to the DOM element (the button), which lacks a buses property, leading to undefined++ , resulting in NaN . Rule of thumb: When passing methods as callbacks, this can lose its original context. To fix, bind the method: // ✅ Correct — bind `purbasha` as 'this' document . querySelector ( ' .buy ' ) . addEventListener ( ' click ' , purbasha . buyBus . bind ( purbasha )); Now, this inside buyBus always refers to purbasha , no matter the event source. Quick Reference Method Executes? Argument Passing Use Case call Yes, immediately Individual args One-off with specific this apply Yes, immediately Arguments in array When data is in an array bind No — returns a new func Pre-set args optional Callbacks, partials That's it! Understanding these methods as different ways to specify "this" makes them less mysterious and more natural to use. Questions? Comments? Feel free to ask! *Inspired by Jonas Schmedtmann's JavaScript course on Udemy. Three little methods. One big idea: you control what this points to. Every time you write a function in JavaScript, there's a hidden element — the this keyword. Usually, it works fine, but when you extract a method or pass it as an event listener, this can point somewhere unexpected, causing confusing bugs. call , apply , and bind are the tools that help manage that hidden element. Let's explore with an example involving a bus company 🚌. The Example Setup Consider Purbasha Paribahan , a local bus company modeled as an object with a book method to record passenger reservations. const purbasha = { busName : ' Purbasha Paribahan ' , busCode : ' PB ' , bookings : [], book : function ( busNum , passengerName ) { console . log ( ` ${ passengerName } has booked a seat on ${ this . busName } with bus ${ this . busCode }${ busNum } .` ); this . bookings . push ({ bus : ` ${ this . busCode }${ busNum } ` , passengerName }); } }; Calling the function normally works perfectly: purbasha . book ( 12 , ' Sumon ' ); Output: Sumon has booked a seat on Purbasha Paribahan with bus PB12. Inside book , this refers to purbasha — exactly as intended. But things get interesting when a rival enters the scene. A competing company, Royal Express , needs similar booking functionality. Repeating the method isn't ideal, so we introduce our three heroes. const royal = { busName : ' Royal Express ' , busCode : ' RE ' , bookings : [] }; Method 1: call — Invoke Immediately with Arguments as a List First, get the book function separately, then use .call() to invoke it with this set to the desired object, passing arguments individually. const book = purbasha . book ; // separate function reference book . call ( royal , 45 , ' Tanvir ' ); Output: Tanvir has booked a seat on Royal Express with bus RE45. What's happening? call runs book immediately, manually setting this to royal . It's like: "Use this function but treat it as if it belongs to royal ". Argument Description 1st Object to assign this 2nd, 3rd, ... Function arguments Method 2: apply — Same as call , Arguments in an Array apply is similar but takes arguments as an array, useful when data is already in an array. const passengerData = [ 23 , ' Mahfuz ' ]; book . apply ( purbasha , passengerData ); Output: Mahfuz has booked a seat on Purbasha Paribahan with bus PB23. Tip: With ES6+, you can use the spread operator with call instead: book.call(purbasha, ...passengerData); Method Argument Passing call Individually listed apply In an array Method 3: bind — Create a New Function with this Set bind doesn't run the function immediately. Instead, it returns a new function with this permanently set, which you can call later. const bookRE = book . bind ( royal ); // new function bookRE ( 56 , ' Mustak ' ); // call the new function Output: Mustak has booked a seat on Royal Express with bus RE56. Using bind for Partial Application bind is especially useful for partial application, where you preset some arguments. // preset `this` and bus number 56 const bookRE56 = book . bind ( royal , 56 ); bookRE56 ( ' Robin ' ); bookRE56 ( ' Rafi ' ); Output: Robin has booked a seat on Royal Express with bus RE56. Rafi has booked a seat on Royal Express with bus RE56. Note: Partial application is creating specialized functions by presetting some arguments. Common Pitfall: Event Callbacks Using object methods as event handlers often causes this to break. Here's an example: purbasha . buses = 100 ; purbasha . buyBus = function () { this . buses ++ ; console . log ( this . buses ); }; // ❌ Wrong — don't do this document . querySelector ( ' .buy ' ) . addEventListener ( ' click ' , purbasha . buyBus ); Click, and you'll see NaN , not 101 . That's because in event callbacks, this refers to the DOM element (the button), which lacks a buses property, leading to undefined++ , resulting in NaN . Rule of thumb: When passing methods as callbacks, this can lose its original context. To fix, bind the method: // ✅ Correct — bind `purbasha` as 'this' document . querySelector ( ' .buy ' ) . addEventListener ( ' click ' , purbasha . buyBus . bind ( purbasha )); Now, this inside buyBus always refers to purbasha , no matter the event source. Quick Reference Method Executes? Argument Passing Use Case call Yes, immediately Individual args One-off with specific this apply Yes, immediately Arguments in array When data is in an array bind No — returns a new func Pre-set args optional Callbacks, partials That's it! Understanding these methods as different ways to specify "this" makes them less mysterious and more natural to use. Questions? Comments? Feel free to ask! *Inspired by Jonas Schmedtmann's JavaScript course on Udemy.