iamsirid.com
สรุปแล้ว "this" หมายถึงอะไรใน javascript
Created At: 14-06-2022 04:18
Last Updated: 14-06-2022 04:19

สรุปแล้ว "this" หมายถึงอะไรใน javascript

หลายคนที่เริ่มเขียนภาษา javascript ใหม่ ๆ คงจะเคยมีปัญหากับ "this" ใน javascript ว่าตกลงมันหมายถึงอะไรกันแน่ ในบล็อกนี้เราจะอธิบาย "this" ให้กระจ่างกัน

อย่างแรกต้องบอกก่อนว่า keyword this ใน javascript เนี่ย ทำตัวแตกต่างจากใน this ในภาษาอื่น ๆ

เพราะว่าโดยส่วนมากแล้ว ค่าของ this จะถูกกำหนดจากว่า function ที่มี this นั้นถูกเรียกใช้อย่างไรในตอน runtime ทำให้แต่ละครั้งที่ฟังก์ชั่นถูกเรียกเนี่ยค่าของ this อาจจะมีค่าที่แตกต่างกันออกไป

เรามาดูการเรียกใช้ this ในแต่ละแบบกัน

แบบแรกคือ Global Context

หรือการเรียกใช้ this ข้างนอกสุด ไม่ได้อยู่ข้างใน function ใด ๆ

console.log(this === window); // true var a = 37; console.log(a); // 37 console.log(window.a); // 37 console.log(this.a); // 37 window.b = 'Hi'; console.log(b); // "Hi" console.log(window.b); // "Hi" console.log(this.b); // "Hi" this.x = 'Hello'; console.log(x); // "Hello" console.log(window.x); // "Hello" console.log(this.x); // "Hello"

ในที่นี้ this จะมีค่าเท่ากับ window object โดย window object เนี่ยก็คือ Global Object นั้นเอง ทำให้การ assign ค่าแต่ละแบบ ไม่ว่าจะเป็นการ assign ค่าแบบเป็น global variable เป็น property ของ window object หรือเป็น property ของ this object ล้วนแล้วก็เป็นค่าเดียวกันนั่นเอง

ใน Function Context

หรือการเรียกใช้ this ข้างใน function ค่าของ this เนี่ยจะขึ้นอยู่กับว่า function นั้นถูกเรียกอย่างไร

var a = 41; function f1() { return this; } f1(); // window f1().a; // 41 var o1 = { a: 42, }; o1.f1 = f1; o1.f1(); // {a: 42, f1: ƒ} (o1 object) o1.f1().a; // 42

เช่นถ้าเราประกาศฟังก์ชั่น f1 ที่ return ค่า this ออกมาเลย แล้วเราเรียก f1 ข้างนอกสุดเราจะได้ว่า this มีค่าเป็น window object นั้นเอง

หรือถ้าเรามี o1 object แล้วเรา assign function f1 ให้กับ o1 object แล้วเรียกใช้ f1 ในแบบที่เป็๋น property ของ o1 เราจะได้ค่า this คือ o1 object นั่นเอง

call(), apply() และ bind()

ซึ่งนอกจากการ assign function เป็น property ของ object ตรง ๆ เองแล้ว เรายังสามารถใช้ method call(), apply() และ bind() ที่เป็น method ที่มีในทุก ๆ function ของ javascript ได้ด้วย

โดย method apply คือการเรียก function นั้นโดยเราสามารถ assign ค่า this เองได้ว่าเป็นอะไร

ตัวอย่างเช่น เรามี function f1 กับ o1 object เหมือนเดิม

var a = 41; function f1() { return this; } f1(); // window f1().a; // 41 var o1 = { a: 42, }; f1.apply(o1); // {a: 42, f1: ƒ} (o1 object) f1.apply(o1).a; // 42

เราสามารถเรียก function f1 โดยใช้ method apply เพื่อ assign ค่า this ให้เป็น o1 object ได้

โดย method apply สามารถรับ argument ตัวที่ 2 เป็น array ของ function นั้นได้ด้วย ตัวอย่างเช่น

function f2(city, country) { return this.firstName + ' ' + this.lastName + ',' + city + ',' + country; } const person1 = { firstName: 'John', lastName: 'Doe', }; f2.apply(person1, ['Bangkok', 'Thailand']); // 'John Doe,Bangkok,Thailand' f3 = f2.bind(person1); f3('Bangkok', 'Thailand');

มี function f2 ที่ return string ที่มาจากค่า firstname และ lastname ของ this และค่า city กับ country ที่รับมาเป็น argument ของ function และมี person1 object ที่มี property firstname และ lastname เป็น string เราสามารถเรียก f2 ได้ด้วย method apply โดยส่ง argument ที่ 2 เป็น array ของ argument ที่ f2 จะรับได้เลย

method อีกตัวชื่อ call จริง ๆ แทบจะเหมือนกับ method apply เลย แต่แค่ไม่ได้รับ argument ตัวที่ 2 เป็น array แต่รับแยกเป็นตัว ๆเลย เช่นจากตัวอย่างที่แล้ว เราสามารถเปลี่ยนจากจากใช้ apply เป็น call ได้แบบนี้

f2.call(person1, 'Bangkok', 'Thailand'); // 'John Doe,Bangkok,Thailand'

สุดท้ายคือ method bind จะคล้าย ๆ apply กับ call แต่แทนที่จะทำการเรียก function นั้นเลย จะเป็นการสร้าง function ใหม่ไว้เรียกทีหลังแทน เช่นจากตัวอย่างที่แล้ว เราสามารถ assign ค่าให้ f3 และเรียกใช้ได้ดังนี้

f3 = f2.bind(person1); f3('Bangkok', 'Thailand'); // 'John Doe,Bangkok,Thailand'

สำหรับกรณี Arrow Function

ค่าของ this จะไม่ได้ขึ้นกับว่า function นั้นถูกเรียกแบบไหน แต่จะได้รับ this มาจาก parent scope คือได้ this มาจาก parent ตอนที่ตัว arrow function ถูก assign ค่านั่นเอง

ตัวอย่างเช่น

const myFunction = () => { return this; }; myFunction(); // window

ในกรณีนี้จะได้ this เป็น window object เช่นเดียวกับ normal function

const myObject = { a: 42, myMethod: () => { return this; }, }; myObject.myMethod(); // window

ในกรณีนี้ this จะเป็น window object เช่นกันเนื่องจาก myMethod ถูก assign ใน myObject ซึ่งมี this เป็น window object

const myObject = { myArrowFunction: null, myMethod: function () { this.myArrowFunction = () => this; return this; }, }; myObject.myMethod(); // myObject myObject.myArrowFunction(); // myObject

ในกรณีนี้จะได้ว่า myArrowFunction ถูก assign ค่าใน normal function ชื่อ myMethod ซึ่งมีค่า this เป็น myObject ดังนั้นค่า this ของ myArrowFunction จึงเป็น myObject เช่นเดียวกัน