ทำความเข้าใจกับ this ใน javascript

ใน javascript มีคีย์เวิร์ด “this” เป็นคำพิเศษที่ถูกใช้ในฟังก์ชัน เพื่ออ้างไปถึง object ที่ใช้ในฟังก์ชันที่ถูกเรียกใช้อยู่ โดยค่าของ this จะเป็นอะไรนั้นก็มีวิธีการพิจารณาเป็นขั้นเป็นตอนอยู่ประมาณนี้



1. ถ้าฟังก์ชันถูกเรียกใช้งานผ่าน .call() หรือ .apply() ค่าของ this ที่ใช้ในฟังก์ชันที่ถูกเรียกจะอ้างไปยัง object ที่เป็น argument แรกที่ส่งเข้ามาในฟังก์ชัน .call()/.apply() ในกรณีที่ไม่มีการส่ง  argument เข้ามาหรือค่าที่ส่งเข้ามามีค่าเป็น null หรือ undefine ค่าของ this จะอ้างไปยัง global object

// เรียกใช้ฟังก์ชันด้วย .call()

var myObject = {
    sayHello: function() {
        console.log( "Hi! My name is " + this.myName );
    },
    myName: "Rebecca"
};

var secondObject = {
    myName: "Colin"
};

myObject.sayHello();                    // "Hi! My name is Rebecca"
myObject.sayHello.call( secondObject ); // "Hi! My name is Colin"

2. ถ้าฟังก์ชันที่กำลังถูกเรียกสร้างมาจากฟังก์ชัน .bind() this ก็จะเป็น argument แรกที่ส่งให้ฟังก์ชัน .bind() ครับ

// A function created using Function.bind()

var myName = "the global object";
var sayHello = function() {
    console.log( "Hi! My name is " + this.myName );
};
var myObject = {
    myName: "Rebecca"
};
var myObjectHello = sayHello.bind( myObject );

sayHello();      // "Hi! My name is the global object"
myObjectHello(); // "Hi! My name is Rebecca"

3. ในกรณีที่ฟังก์ชันอยู่ภายใต้ object และถุกเรียกใช้งานผ่าน object this จะหมายถึง object นั้นๆ ครับ

// A function being attached to an object at runtime.

var myName = "the global object";
var sayHello = function() {
    console.log( "Hi! My name is " + this.myName );
};
var myObject = {
    myName: "Rebecca"
};
var secondObject = {
    myName: "Colin"
};

myObject.sayHello = sayHello;
secondObject.sayHello = sayHello;

sayHello();              // "Hi! My name is the global object"
myObject.sayHello();     // "Hi! My name is Rebecca"
secondObject.sayHello(); // "Hi! My name is Colin"

4. นอกเหนือจากที่กล่าวมา ถ้าฟังก์ชันไม่ได้อยุ่ภายใต้ object อะไรเลยแล้วถูกเรียกใช้เลย this จะอ้างถึง global object ครับผม ^^

ในกรณีที่เรามีการสร้างฟังก์ชันไว้ภายใต้ namespace ที่ยาวๆ ไม่ควรจะสร้างตัวแปรขึ้นมาอ้างไปยังฟังก์ชันที่อยู่ใน namespace นั้นๆ เพราะจะทำให้ค่าของ this ไม่ถูกต้องได้ เช่น

var myNamespace = {
    myObject: {
        sayHello: function() {
            console.log( "Hi! My name is " + this.myName );
        },
        myName: "Rebecca"
    }
};
 
var hello = myNamespace.myObject.sayHello;
 
hello(); // "Hi! My name is undefined"

ถ้าต้องการจะย่อลงมาจริงๆ ก็ควรจะเอาให้ถึงแค่ object ที่เป็นเจ้าของฟังก์ชันที่เราต้องการจะเรียกก็พอครับ

var myNamespace = {
    myObject: {
        sayHello: function() {
            console.log( "Hi! My name is " + this.myName );
        },
        myName: "Rebecca"
    }
};
 
var obj = myNamespace.myObject;
 
obj.sayHello(); // "Hi! My name is Rebecca"

สามารถอ่านข้อมูลเพิ่มเติมได้ที่นี่เลยครับ: The “this” Keyword | jQuery Learning Center