PEAN Stack Day 3 - This, Bind, Call, Apply
Day 3: This
, Bind
, Call
, Apply
trong Javascript
Hãy cùng mình tìm hiểu một chút về this
, bind
, call
, và apply
trong Javascript nhé! Đôi khi việc làm quen với những khái niệm này có thể hơi rối bời, nhưng sau khi đã hiểu rõ, các bạn sẽ thấy chúng thực sự hữu ích.
1. This
trong Javascript
1.1. Khái niệm cơ bản
this
không phải là một biến cố định, mà giá trị của nó thay đổi tùy theo cách gọi hàm.
1.2. Ví dụ
-
Ví dụ 1: Trong method của object:
const person = { name: 'An', greet: function() { console.log(`Hello, my name is ${this.name}`); } }; person.greet(); // Hello, my name is An
Giải thích: Ở đây,
this
tronggreet
method chính là đối tượngperson
vì method được gọi từ object đó. Do đó,this.name
sẽ trả về "An". -
Ví dụ 2: Khi gọi một hàm bình thường:
function introduce() { console.log(this); } introduce(); // Window {...}
Giải thích: Khi một hàm bình thường được gọi (không thông qua một đối tượng hoặc không được bind),
this
mặc định sẽ trỏ đếnwindow
(trong trình duyệt). -
Ví dụ 3: Khi dùng
this
trong một hàm callback:const myBtn = document.querySelector('.myBtn'); myBtn.addEventListener('click', function() { console.log(this); // <button class="myBtn">Click me!</button> });
Giải thích: Trong trường hợp này,
this
chính là element mà sự kiện được gắn lên, trong trường hợp này là nút.myBtn
.
2. Bind
Bind
, Call
và Apply
: Ba thằng này đơn giản giúp chúng ta kiểm soát cách sử dụng this
.
2.1. Khái niệm
bind
giúp chúng ta "ép buộc" một giá trị cụ thể cho this
trong một function.
2.2. Ví dụ
-
Ví dụ 1:
function greet() { console.log(`Hello, my name is ${this.name}`); } const person = { name: 'Bao' }; const boundGreet = greet.bind(person); boundGreet(); // Hello, my name is Bao
Giải thích: Dùng
bind
, ta có thể "ép"this
trong hàmgreet
trỏ đến đối tượngperson
. Vì vậy, khi gọiboundGreet()
, giá trị củathis.name
sẽ là "Bao". -
Ví dụ 2:
const timer = { seconds: 10, start: function() { setInterval(function() { if(this.seconds > 0) { console.log(this.seconds--); } }.bind(this), 1000); } }; timer.start();
Giải thích: Ở đây, nếu không có
bind(this)
, giá trị củathis
trong hàm callback củasetInterval
sẽ trở thànhwindow
, không phải là đối tượngtimer
. Nhưng nhờbind(this)
,this
giữ nguyên làtimer
và code hoạt động như mong đợi.
3. Call
và Apply
3.1. Khái niệm
Cả hai đều dùng để gọi hàm với một giá trị this
và các tham số cụ thể. Khác biệt chính là cách truyền tham số: call
truyền trực tiếp, còn apply
truyền qua một mảng.
3.2. Ví dụ
-
Ví dụ với
call
:function introduce(hobby1, hobby2) { console.log(`Hello, I'm ${this.name}. I like ${hobby1} and ${hobby2}`); } const person = { name: 'Minh' }; introduce.call(person, 'coding', 'reading');
Giải thích: Ở đây, chúng ta dùng
call
để gọi hàmintroduce
vớithis
làperson
và hai tham số là 'coding' và 'reading'. -
Ví dụ với
apply
:function introduce(hobbies) { console.log(`Hello, I'm ${this.name}. I like ${hobbies.join(' and ')}`); } const person = { name: 'Hoa' }; introduce.apply(person, [['singing', 'dancing']]);
Giải thích: Khác với
call
,apply
yêu cầu truyền tham số dưới dạng một mảng. Ở đây, chúng ta truyền một mảng gồm hai phần tử 'singing' và 'dancing'.
English Version
Hey, friends! 🖐 Let's chat about a few cool things in Javascript: this
, bind
, call
, and apply
. They might seem a bit confusing at first, but trust me, once you get them, they're super handy!
1. The Magic of This
in Javascript
1.1. What's it all about?
Imagine this
as a magic word that doesn't always mean the same thing. It changes depending on how we're using it in our code.
1.2. Show me some examples!
-
Example 1: Inside an object method:
const person = { name: 'An', greet: function() { console.log(`Hello, my name is ${this.name}`); } }; person.greet(); // Outputs: Hello, my name is An
Plain Talk: Here,
this
means theperson
object because the method is part of that object. So,this.name
gives us "An". -
Example 2: Calling a regular function:
function introduce() { console.log(this); } introduce(); // Outputs: Window {...}
Plain Talk: If you just call a normal function without tying it to anything,
this
just points to the whole browser window. -
Example 3: Using
this
in a callback:const myBtn = document.querySelector('.myBtn'); myBtn.addEventListener('click', function() { console.log(this); });
Plain Talk: Here,
this
is pointing to the button we clicked on, the one with.myBtn
class.
2. The Power of Bind
The trio of Bind
, Call
, and Apply
help us tell Javascript exactly what we want this
to mean.
2.1. What's it about?
bind
is like telling a function: "Hey, I want you to use this
value every time you're called!"
2.2. Give me examples!
-
Example 1:
function greet() { console.log(`Hello, my name is ${this.name}`); } const person = { name: 'Bao' }; const boundGreet = greet.bind(person); boundGreet(); // Outputs: Hello, my name is Bao
Plain Talk: With
bind
, we told the function to think ofthis
as theperson
object. So, when we called it,this.name
meant "Bao". -
Example 2:
const timer = { seconds: 10, start: function() { setInterval(function() { if(this.seconds > 0) { console.log(this.seconds--); } }.bind(this), 1000); } }; timer.start();
Plain Talk: If we didn't use
bind(this)
, the function would get confused and thinkthis
was the whole browser window. But thanks tobind(this)
, it correctly thinks ofthis
as thetimer
object.
3. Dive into Call
& Apply
3.1. What are these?
Both call
and apply
let us call a function and tell it what this
should be. They're like siblings but have a tiny difference in how they want their info.
3.2. Show and tell, please!
-
Example with
call
:function introduce(hobby1, hobby2) { console.log(`Hello, I'm ${this.name}. I like ${hobby1} and ${hobby2}`); } const person = { name: 'Minh' }; introduce.call(person, 'coding', 'reading');
Plain Talk: Here, we're telling the function to use
person
asthis
. And, we're giving it two hobbies directly. -
Example with
apply
:function introduce(hobbies) { console.log(`Hello, I'm ${this.name}. I like ${hobbies.join(' and ')}`); } const person = { name: 'Hoa' }; introduce.apply(person, [['singing', 'dancing']]);
Plain Talk: The difference is,
apply
wants the hobbies in a list, like a shopping list. So we give it a list of hobbies.
Hope that clears things up! Remember, practice makes perfect. Keep coding and have fun! 🚀🤓🎉
日本語版
さあ、JavaScriptでのthis
、bind
、call
、そしてapply
について一緒に学ぼう!
1. JavaScriptでのThis
1.1. 基本
this
は固定の変数じゃないよ。どのように関数を呼び出すかで、this
の値が変わるんだ。
1.2. 例
-
例1: オブジェクトのメソッド内:
const person = { name: 'An', greet: function() { console.log(`こんにちは、私の名前は${this.name}です`); } }; person.greet(); // こんにちは、私の名前はAnです
説明: この場合、
greet
メソッドの中のthis
はperson
オブジェクトだよ。だから、this.name
は"An"となるよ。 -
例2: 通常の関数を呼び出す場合:
function introduce() { console.log(this); } introduce(); // Window {...}
説明: ここでは、普通の関数が呼び出されると、
this
はデフォルトでwindow
を指すよ(ブラウザ内での話)。 -
例3: コールバック関数での
this
:const myBtn = document.querySelector('.myBtn'); myBtn.addEventListener('click', function() { console.log(this); // <button class="myBtn">私をクリック!</button> });
説明: この場合、
this
はイベントが追加された要素、つまり.myBtn
ボタンを指すよ。
2. Bind
Bind
やCall
、Apply
は、this
を使う方法をコントロールするのを助けてくれるツールだよ。
2.1. 基本
bind
を使うと、関数の中のthis
の値を指定できるんだ。
2.2. 例
-
例1:
function greet() { console.log(`こんにちは、私の名前は${this.name}です`); } const person = { name: 'Bao' }; const boundGreet = greet.bind(person); boundGreet(); // こんにちは、私の名前はBaoです
説明:
bind
を使うと、greet
関数の中のthis
をperson
オブジェクトに結び付けることができるよ。だから、boundGreet()
を呼び出すと、this.name
の値は"Bao"になるよ。 -
例2:
const timer = { seconds: 10, start: function() { setInterval(function() { if(this.seconds > 0) { console.log(this.seconds--); } }.bind(this), 1000); } }; timer.start();
説明: この場合、
bind(this)
がないと、setInterval
のコールバック内のthis
はwindow
になるよ。しかし、bind(this)
のおかげで、this
はtimer
のままだよ。
3. Call
とApply
3.1. 基本
これらは、特定のthis
の値と引数で関数を呼び出すためのものだよ。違いは引数の渡し方だけ:call
は直接、apply
は配列を使って渡すよ。
3.2. 例
-
call
の例:function introduce(hobby1, hobby2) { console.log(`こんにちは、私は${this.name}です。${hobby1}と${hobby2}が好きです`); } const person = { name: 'Minh' }; introduce.call(person, 'コーディング', '読書');
説明: ここでは、
call
を使ってintroduce
関数をthis
がperson
で、引数が'コーディング'と'読書'で呼び出しているよ。 -
apply
の例:function introduce(hobbies) { console.log(`こんにちは、私は${this.name}です。${hobbies.join('と')}が好きです`); } const person = { name: 'Hoa' }; introduce.apply(person, [['歌うこと', '踊ること']]);
説明:
apply
は、引数を配列として渡す必要があるよ。この場合、'歌うこと'と'踊ること'の2つの要素を持つ配列を渡しているよ。
希望これが役立ちます!何か質問があれば、お気軽にどうぞ!
Mình hy vọng bạn thích bài viết này và học thêm được điều gì đó mới.
Donate mình một ly cafe hoặc 1 cây bút bi để mình có thêm động lực cho ra nhiều bài viết hay và chất lượng hơn trong tương lai nhé. À mà nếu bạn có bất kỳ câu hỏi nào thì đừng ngại comment hoặc liên hệ mình qua: Zalo - 0374226770 hoặc Facebook. Mình xin cảm ơn.
Momo: NGUYỄN ANH TUẤN - 0374226770
TPBank: NGUYỄN ANH TUẤN - 0374226770 (hoặc 01681423001)
All rights reserved