- vừa được xem lúc

Blog#328: PEAN Stack Day 3 - This, Bind, Call, Apply (Song ngữ: VN - EN - JP)

0 0 6

Người đăng: NGUYỄN ANH TUẤN

Theo Viblo Asia

Hi các bạn, mình là TUẤN. Hiện đang là một Full-stack Web Developer tại Tokyo😊.

Nếu bạn thích bài viết, xin hãy cho mình 1 upvote và follow blog để ủng hộ mình có thêm động lực ra thêm nhiều bài viết hay hơn trong tương lại nhé.😊

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 trong greet method chính là đối tượng person 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ỏ đến window (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, CallApply: 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àm greet trỏ đến đối tượng person. Vì vậy, khi gọi boundGreet(), giá trị của this.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ủa this trong hàm callback của setInterval sẽ trở thành window, không phải là đối tượng timer. Nhưng nhờ bind(this), this giữ nguyên là timer và code hoạt động như mong đợi.

3. CallApply

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àm introduce với thisperson 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 the person 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 of this as the person 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 think this was the whole browser window. But thanks to bind(this), it correctly thinks of this as the timer 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 as this. 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でのthisbindcall、そして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メソッドの中のthispersonオブジェクトだよ。だから、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

BindCallApplyは、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関数の中のthispersonオブジェクトに結び付けることができるよ。だから、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のコールバック内のthiswindowになるよ。しかし、bind(this)のおかげで、thistimerのままだよ。

3. CallApply

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関数をthispersonで、引数が'コーディング'と'読書'で呼び出しているよ。

  • applyの例:

    function introduce(hobbies) { console.log(`こんにちは、私は${this.name}です。${hobbies.join('と')}が好きです`);
    }
    const person = { name: 'Hoa'
    };
    introduce.apply(person, [['歌うこと', '踊ること']]);
    

    説明: applyは、引数を配列として渡す必要があるよ。この場合、'歌うこと'と'踊ること'の2つの要素を持つ配列を渡しているよ。

希望これが役立ちます!何か質問があれば、お気軽にどうぞ!

Cuối cùng

Như thường lệ, mình hy vọng bạn thích bài viết này và biết thêm được điều gì đó mới.

Nếu bạn thích bài viết, xin hãy cho mình 1 upvote và đăng ký để ủng hộ mình có thêm động lực ra thêm nhiều bài viết hay hơn trong tương lại nhé.

Cảm ơn và hẹn gặp bạn trong những bài viết tiếp theo. Thank you. 😊


Ae nào có dự định trở thành Dev hoặc BrSE tại Nhật (N3-N4, 2-3 năm exp trở lên hoặc zero tech có tiếng N1-N2, cả 2 đầu Nhật và VN) cần mình đưa roadmap hoặc review CV, hiểu hơn về các câu hỏi thường gặp khi interview Dev hoặc BrSE, cách deal lương cao... cần support thì cứ liên hệ mình qua zalo nhé: 0379302361 hoặc Facebook của mình. Hoặc có bất kỳ vấn đề về kỹ thuật nào cần hỏi thì cứ liên hệ mình nhé.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Blog#173: Introduction to Advanced JavaScript Concepts - Advanced JavaScript Part 1

Hi, I'm Tuan, a Full-stack Web Developer from Tokyo . JavaScript is an essential language for web development, and learning advanced concepts can significantly improve your programming skills.

0 0 11

- vừa được xem lúc

Blog#174: 🤔Understanding Asynchronous JavaScript: 🔄Callbacks, 🤞Promises, and 🤝Async/Await

Hi, I'm Tuan, a Full-stack Web Developer from Tokyo . 1. Introduction to Asynchronous JavaScript. What is Asynchronous JavaScript.

0 0 13

- vừa được xem lúc

Blog#175: 🧐Mastering JavaScript's Execution Context and Closures🚀

Hi, I'm Tuan, a Full-stack Web Developer from Tokyo . 1. Understanding Execution Context. A Quick Overview.

0 0 9

- vừa được xem lúc

Blog#177: 🤔MAYBE YOU DON'T KNOW - 👌Using Node-Postgres in Node.js Express✨

Hi, I'm Tuan, a Full-stack Web Developer from Tokyo . In this article, we'll walk you through a step-by-step guide on using node-postgres with Node.

0 0 12

- vừa được xem lúc

Blog#176: 💪The Power of JavaScript Functional Programming🚀

. The main goal of this article is to help you improve your English level. I will use Simple English to introduce to you the concepts related to software development.

0 0 13

- vừa được xem lúc

[Javascript] Nâng cấp kỹ thuật tạo Tham số trong Hàm JS

1. Khái niệm.

0 0 14