คีย์เวิร์ด this
หมายถึงค่าของออบเจ็กต์ที่เชื่อมโยงกับ
ในขณะที่เรียกใช้ ซึ่งหมายความว่าค่าจะแตกต่างกันไปตาม
ว่าฟังก์ชันถูกเรียกเป็นเมธอด เป็นฟังก์ชันแบบสแตนด์อโลน หรือเป็นฟังก์ชัน
เครื่องมือสร้าง
เมื่อมีการเรียกฟังก์ชัน ฟังก์ชันจะสร้างอินสแตนซ์ของคีย์เวิร์ด this
ที่อยู่ด้านหลัง
ฉากต่างๆ เป็นการอ้างอิงไปยังวัตถุที่มีฟังก์ชันนั้น ซึ่งทำให้
เข้าถึงพร็อพเพอร์ตี้และเมธอดที่กำหนดไว้ควบคู่กันไปจากภายในขอบเขต
การทำงานกับ this
มีความคล้ายคลึงกับการทำงานกับตัวแปรที่ประกาศไว้
ด้วย const
นํา this
ออกและค่าของค่าคงที่ไม่ได้
กำหนดใหม่ แต่วิธีการและพร็อพเพอร์ตี้ของออบเจ็กต์ที่คีย์เวิร์ด this
"มี" สามารถแก้ไขได้
การเชื่อมโยงส่วนกลาง
ภายนอกฟังก์ชันหรือบริบทของออบเจ็กต์ this
หมายถึง
พร็อพเพอร์ตี้ globalThis
ซึ่งเป็นการอ้างอิงไปยังออบเจ็กต์ส่วนกลางส่วนใหญ่
สภาพแวดล้อม JavaScript ในบริบทของสคริปต์ที่ทำงานในเว็บเบราว์เซอร์
ออบเจ็กต์ส่วนกลางคือออบเจ็กต์ window
:
this;
> Window {0: Window, window: Window, self: Window, document: document, name: '', location: Location, ...}
ใน Node.js globalThis
คือออบเจ็กต์ global
:
$ node
Welcome to Node.js v20.10.0.
Type ".help" for more information.
> this
<ref *1> Object [global] {
...
}
ภายนอกโหมดเข้มงวด this
ยังหมายถึงออบเจ็กต์ส่วนกลางภายในสแตนด์อโลนด้วย
เนื่องจาก Window
ระดับบนเป็นออบเจ็กต์ที่ "เป็นเจ้าของ" ได้อย่างมีประสิทธิภาพ
ฟังก์ชันเหล่านั้น
function myFunction() {
console.log( this );
}
myFunction();
> Window {...}
(function() {
console.log( this );
}());
> Window {...}
เมื่อใช้โหมดจำกัด this
จะมีค่าเป็น undefined
ภายในแบบสแตนด์อโลน
ฟังก์ชัน:
(function() {
"use strict";
console.log( this );
}());
> undefined
ก่อนเริ่มใช้โหมดเข้มงวด ค่า null
หรือ undefined
สำหรับ this
จะถูกแทนที่ด้วยการอ้างอิงออบเจ็กต์ส่วนกลาง บางครั้งคุณอาจเห็น
การเชื่อมโยงส่วนกลางเรียกว่า "การเชื่อมโยงเริ่มต้น" เนื่องจากลักษณะการทำงานแบบเดิมนี้
การเชื่อมโยงโดยนัย
เมื่อมีการเรียกฟังก์ชันเป็นเมธอดของออบเจ็กต์ อินสแตนซ์ของ this
ที่อยู่ข้างใน
เมธอดนั้นอ้างอิงถึงออบเจ็กต์ที่มีเมธอด ซึ่งให้สิทธิ์การเข้าถึง
วิธีการและพร็อพเพอร์ตี้ที่เกี่ยวข้อง
let myObject = {
myValue: "This is my string.",
myMethod() {
console.log( this.myValue );
}
};
myObject.myMethod();
> "This is my string."
อาจดูเหมือนค่าของ this
ขึ้นอยู่กับวิธีที่ฟังก์ชันและ
มีการกำหนดออบเจ็กต์ที่ล้อมรอบอยู่ แต่บริบทสำหรับค่าของ this
จะเป็น
บริบทการดำเนินการปัจจุบัน ในกรณีนี้ บริบทของการดำเนินการคือ
ออบเจ็กต์ myObject
กำลังเรียกใช้เมธอด myMethod
ดังนั้น myObject
จะเป็นค่า
เป็นเวลา this
นี่อาจดูเหมือนทางเทคนิคในบริบทของ
ตัวอย่าง แต่สำหรับการใช้งานขั้นสูงขึ้นของ this
ความแตกต่างที่สำคัญคือ
ที่ควรคำนึงถึง
โดยทั่วไปแล้ว ให้ใช้ this
ในลักษณะที่ไม่คาดหวังว่าโค้ดรอบๆ จะต้องมี
โครงสร้างเฉพาะใดๆ ข้อยกเว้นสำหรับกฎนี้คือ ES5
ฟังก์ชันลูกศร
this
ในฟังก์ชันลูกศร
ในฟังก์ชันลูกศร
this
เปลี่ยนเป็นการเชื่อมโยงใน
สภาพแวดล้อมโดยรอบที่ล้อมรอบด้วยคำศัพท์ ซึ่งหมายความว่า
this
ในฟังก์ชันลูกศรหมายถึงค่าของ this
ในฟังก์ชันดังกล่าว
บริบทแวดล้อมที่ใกล้เคียงที่สุด:
let myObject = {
myMethod() { console.log( this ); },
myArrowFunction: () => console.log( this ),
myEnclosingMethod: function () {
this.myArrowFunction = () => { console.log(this) };
}
};
myObject.myMethod();
> Object { myMethod: myMethod(), myArrowFunction: myArrowFunction() }
myObject.myArrowFunction();
> Window {...}
ในตัวอย่างก่อนหน้า myObject.myMethod()
บันทึก myObject
เป็นออบเจ็กต์
ที่ "เป็นเจ้าของ" เมธอดนั้น แต่ myObject.myArrowFunction()
แสดงผล globalThis
(หรือ undefined
) เนื่องจากอินสแตนซ์ของ this
ภายในฟังก์ชันลูกศร
อ้างอิงถึงขอบเขตสูงสุดที่ครอบคลุมแทน
ในตัวอย่างต่อไปนี้ myEnclosingMethod
จะสร้างฟังก์ชันลูกศรใน
ที่มีคำสั่งนั้นอยู่เมื่อเรียกใช้ อินสแตนซ์ของ this
ภายใน
ตอนนี้ฟังก์ชันลูกศรหมายถึงค่าของ this
ภายในค่าที่ล้อมรอบ
ซึ่งเป็นเมธอดที่มีฟังก์ชันลูกศรนั้นอยู่ เนื่องจาก
ค่าของ this
ภายใน myEnclosingMethod
จะหมายถึง myObject
หลังจากที่คุณ
กำหนดฟังก์ชันลูกศร this
ภายในฟังก์ชันลูกศรจะหมายถึง
myObject
:
let myObject = {
myMethod() { console.log( this ); },
myEnclosingMethod: function () {
this.myArrowFunction = () => { console.log(this) };
}
};
myObject.myEnclosingMethod();
myObject.myArrowFunction();
> Object { myMethod: myMethod(), myArrowFunction: myArrowFunction() }
การเชื่อมโยงที่ชัดเจน
การเชื่อมโยงโดยนัยจะจัดการ Use Case ส่วนใหญ่สำหรับการทำงานกับ this
อย่างไรก็ตาม คุณ
บางครั้งอาจต้องใช้ค่า this
เพื่อแสดงการดำเนินการที่เจาะจง
แทนที่จะใช้บริบทสมมติ ภาพประกอบหากล้าสมัยเล็กน้อย
ตัวอย่างเช่น กำลังทำงานกับ this
ภายในฟังก์ชัน Callback ของ setTimeout
เนื่องจาก Callback นี้มีบริบทการดำเนินการที่ไม่ซ้ำกัน
var myObject = {
myString: "This is my string.",
myMethod() {
console.log( this.myString );
}
};
myObject.myMethod();
> "This is my string."
setTimeout( myObject.myMethod, 100 );
> undefined
แม้ว่าข้อบกพร่องเฉพาะนี้ของ setTimeout
จะได้รับการแก้ไขโดย
ฟีเจอร์อื่นๆ หรือปัญหาคล้ายๆ กันว่า "สูญหาย" this
เคยมีการจ่าหน้าถึงก่อนหน้านี้แล้ว
โดยการสร้างการอ้างอิงที่ชัดแจ้งไปยังค่าของ this
ภายในขอบเขตของ
บริบทที่ต้องการ บางครั้งคุณอาจเห็นอินสแตนซ์ของ this
ที่กำลังถูกกำหนด
ไปยังตัวแปรโดยใช้ตัวระบุ เช่น that
, self
หรือ _this
ในแบบเดิม
ฐานของโค้ด ต่อไปนี้เป็นแบบแผนตัวระบุทั่วไปสำหรับตัวแปรที่มี
ส่งค่า this
เมื่อเรียกใช้ฟังก์ชันโดยใช้เมธอด call()
, bind()
หรือ apply()
this
อ้างอิงออบเจ็กต์ที่เรียกใช้อย่างชัดเจน:
let myFunction = function() {
console.log( this.myValue );
}
let myObject = {
"myValue" : "This is my string."
};
myFunction.call( myObject );
> "This is my string."
var myObject = {
myString: "This is my string.",
myMethod() {
console.log( this.myString );
}
};
setTimeout( myObject.myMethod.bind( myObject ), 100 );
> "This is my string."
การเชื่อมโยงที่ชัดเจนจะลบล้างค่า this
ที่ได้จากการเชื่อมโยงโดยนัย
let myObject = {
"myValue" : "This string sits alongside myMethod.",
myMethod() {
console.log( this.myValue );
}
};
let myOtherObject = {
"myValue" : "This is a string in another object entirely.",
};
myObject.myMethod.call( myOtherObject );
> "This is a string in another object entirely."
หากมีการเรียกฟังก์ชันในลักษณะที่จะตั้งค่า this
เป็น
undefined
หรือ null
ค่านั้นจะแทนที่ด้วย globalThis
นอกข้อจำกัด
โหมด:
let myFunction = function() {
console.log( this );
}
myFunction.call( null );
> Window {...}
ในทำนองเดียวกัน หากมีการเรียกฟังก์ชันในลักษณะที่จะทำให้ this
มีค่าพื้นฐาน
ค่าดังกล่าวจะแทนที่ด้วย
ออบเจ็กต์ Wrapper ของค่าพื้นฐาน
ภายนอกโหมดเข้มงวด:
let myFunction = function() {
console.log( this );
}
let myNumber = 10;
myFunction.call( myNumber );
> Number { 10 }
ในโหมดเข้มงวด ระบบจะไม่เปลี่ยนค่า this
ที่ส่งผ่านไปยังออบเจ็กต์ไม่ว่าในลักษณะใด
แม้ว่าจะเป็นค่าพื้นฐาน, null
หรือ undefined
:
"use strict";
let myFunction = function() {
console.log( this );
}
let myNumber = 10;
myFunction.call( myNumber );
> 10
myFunction.call( null );
> null
การผูก new
เมื่อมีการใช้ class เป็นเครื่องมือสร้างโดยใช้เมธอด
คีย์เวิร์ด new
รายการ this
หมายถึงอินสแตนซ์ที่สร้างขึ้นใหม่:
class MyClass {
myString;
constructor() {
this.myString = "My string.";
}
logThis() {
console.log( this );
}
}
const thisClass = new MyClass();
thisClass.logThis();
> Object { myString: "My string." }
ในทำนองเดียวกัน ค่าของ this
ภายในฟังก์ชันตัวสร้างที่เรียกใช้ new
หมายถึงออบเจ็กต์ที่ถูกสร้างขึ้น:
function MyFunction() {
this.myString = "My string.";
this.logThis = function() {
console.log( this );
}
}
const myObject = new MyFunction();
myObject.logThis();
> Object { myString: "My string.", logThis: logThis() }
การเชื่อมโยงเครื่องจัดการเหตุการณ์
ในบริบทของเครื่องจัดการเหตุการณ์ ค่าของ this
จะอ้างอิงออบเจ็กต์ที่
เรียกใช้ ภายในฟังก์ชัน Callback ของตัวแฮนเดิลเหตุการณ์ ซึ่งหมายความว่า this
อ้างอิงองค์ประกอบที่เชื่อมโยงกับเครื่องจัดการ:
let button = document.querySelector( "button" );
button.addEventListener( "click", function( event ) { console.log( this ); } );
เมื่อผู้ใช้โต้ตอบกับ button
ในข้อมูลโค้ดก่อนหน้า ผลลัพธ์ที่ได้คือ
ออบเจ็กต์องค์ประกอบที่มี <button>
อยู่:
> Button {}
เมื่อใช้ฟังก์ชันลูกศรเป็น Callback สำหรับ Listener เหตุการณ์ ค่าของ
มีการระบุ this
อีกครั้งโดยบริบทการดำเนินการที่อยู่รอบๆ ที่ใกล้เคียงที่สุด ที่ด้านบน
ซึ่งหมายความว่า this
ภายในฟังก์ชัน Callback ของตัวแฮนเดิลเหตุการณ์คือ
globalThis
(หรือ undefined
ในโหมดเข้มงวด):
let button = document.querySelector( "button" );
button.addEventListener( "click", ( event ) => { console.log( this ); } );
> undefined
เช่นเดียวกับออบเจ็กต์อื่นๆ เมื่อคุณใช้ call()
, bind()
หรือ apply()
เมธอดในการอ้างอิงฟังก์ชัน Callback ของ Listener เหตุการณ์ this
อ้างอิงออบเจ็กต์อย่างชัดเจน เช่น
let button = document.querySelector( "button" );
let myObject = {
"myValue" : true
};
function handleClick() {
console.log( this );
}
button.addEventListener( "click", handleClick.bind( myObject ) );
> Object { myValue: true }
ตรวจสอบความเข้าใจ
สำหรับสคริปต์ที่ทำงานในเว็บเบราว์เซอร์ ออบเจ็กต์ส่วนกลางคืออะไร
ที่ this
หมายถึงเมื่อใช้ภายนอกฟังก์ชัน หรือ
บริบทของออบเจ็กต์หรือไม่
window
browser
undefined