ข้ามไปยังเนื้อหา

this และ Context

this เป็น keyword พิเศษที่อ้างถึง execution context — object ที่ถือเป็น receiver ของการเรียกฟังก์ชันปัจจุบัน ต่างจากภาษาส่วนใหญ่ this ใน JavaScript ไม่ถูก bind เมื่อนิยาม แต่ถูกกำหนด ณ เวลาที่เรียก โดยวิธีที่ฟังก์ชันถูก invoke

// 1. Method call — this คือ object ก่อนจุด
const user = {
name: 'Alice',
greet: function() {
return 'Hi, I am ' + this.name;
},
};
console.log(user.greet()); // 'Hi, I am Alice'
// 2. Plain function call — this คือ undefined (strict mode) หรือ globalThis
function whoAmI() {
return typeof this; // 'undefined' ใน strict mode
}
// 3. Constructor call — this คือ object ที่สร้างใหม่
function Person(name) {
this.name = name;
}
const p = new Person('Bob');
console.log(p.name); // 'Bob'

ปัญหาที่พบบ่อยที่สุด: การแยก method ออกจาก object ทำให้ binding หาย

const timer = {
label: 'tick',
start: function() {
// หลังจาก 0 ms fn ถูกเรียกเป็น plain function — this.label เป็น undefined
setTimeout(function() {
console.log(this.label); // undefined — 'this' ไม่ใช่ timer
}, 0);
},
};

ทั้งสาม method นี้ให้คุณ กำหนด this อย่างชัดเจน

function introduce(greeting, punctuation) {
return greeting + ', I am ' + this.name + punctuation;
}
const obj = { name: 'Carol' };
// call — ส่ง arguments แยกกัน
introduce.call(obj, 'Hello', '!'); // 'Hello, I am Carol!'
// apply — ส่ง arguments เป็น array
introduce.apply(obj, ['Hey', '.']); // 'Hey, I am Carol.'
// bind — return ฟังก์ชันใหม่ที่ this ถูก bind อย่างถาวร
const boundIntroduce = introduce.bind(obj);
boundIntroduce('Hi', '?'); // 'Hi, I am Carol?'

Arrow functions ไม่มี this ของตัวเอง แต่ inherit this จาก lexical enclosing scope — function หรือ module scope รอบนอกที่จุดที่เขียน

const timer2 = {
label: 'tick',
start: function() {
// Arrow function inherit 'this' จาก start() — ซึ่งคือ timer2
setTimeout(() => {
console.log(this.label); // 'tick' — bound อย่างถูกต้อง
}, 0);
},
};

ทำให้ arrow functions เป็นตัวเลือกที่เหมาะสมสำหรับ callbacks ภายใน methods

JavaScript
`this` ของ regular function (non-arrow) ใน JavaScript ถูกกำหนดเมื่อไหร่?
`fn.bind(obj)` return อะไร?
ทำไม arrow functions จึงทำงานได้ดีเป็น callbacks ภายใน class methods?