Kata kunci this
mengacu pada nilai objek yang terikat dengan
fungsi pada saat panggilannya, yang berarti bahwa nilainya berbeda tergantung
apakah suatu fungsi dipanggil sebagai metode, sebagai fungsi mandiri, atau sebagai
konstruktor.
Saat dipanggil, fungsi akan membuat instance kata kunci this
di belakang
layar sebagai referensi ke objek yang berisi fungsi tersebut, memberikan
akses ke properti dan metode yang ditentukan
di samping itu dari dalam cakupannya.
Menggunakan this
memiliki kemiripan dengan beberapa cara menggunakan variabel yang dideklarasikan
dengan const
. Seperti konstanta, this
tidak dapat dihapus dan nilainya tidak dapat
ditetapkan ulang, tetapi metode dan properti objek yang ditetapkan oleh kata kunci this
dapat diubah.
Binding global
Di luar fungsi atau konteks objek, this
mengacu pada
globalThis
, yang merupakan referensi ke objek global dalam sebagian besar
lingkungan JavaScript. Dalam konteks skrip yang
berjalan di {i>browser<i} web,
objek global adalah objek window
:
this;
> Window {0: Window, window: Window, self: Window, document: document, name: '', location: Location, ...}
Di Node.js, globalThis
adalah objek global
:
$ node
Welcome to Node.js v20.10.0.
Type ".help" for more information.
> this
<ref *1> Object [global] {
...
}
Di luar mode ketat, this
juga merujuk pada objek global di dalam mode mandiri
, karena Window
induk adalah objek yang secara efektif "memiliki"
fungsi-fungsi tersebut.
function myFunction() {
console.log( this );
}
myFunction();
> Window {...}
(function() {
console.log( this );
}());
> Window {...}
Saat menggunakan mode ketat, this
memiliki nilai undefined
di dalam mode mandiri
{i>function<i}:
(function() {
"use strict";
console.log( this );
}());
> undefined
Sebelum pengenalan mode ketat, nilai null
atau undefined
untuk this
akan diganti dengan referensi ke objek global. Terkadang Anda
mungkin melihat
binding global disebut sebagai "binding default" karena perilaku lama ini.
Binding implisit
Saat sebuah fungsi dipanggil sebagai metode suatu objek, instance this
di dalam
metode itu mengacu pada objek yang
berisi metode, yang memberikan akses ke
metode dan properti yang menyertainya:
let myObject = {
myValue: "This is my string.",
myMethod() {
console.log( this.myValue );
}
};
myObject.myMethod();
> "This is my string."
Sepertinya nilai this
bergantung pada cara fungsi dan
objek yang mencakup ditentukan. Sebaliknya, konteks untuk nilai this
adalah
konteks eksekusi saat ini. Dalam hal ini, konteks eksekusinya adalah
Objek myObject
memanggil metode myMethod
sehingga myObject
adalah nilainya
untuk this
. Hal ini mungkin tampak seperti hal teknis
dalam konteks
contoh ini, tetapi untuk penggunaan lanjutan this
, ini adalah perbedaan penting
versi tersebut adalah beberapa file.
Secara umum, gunakan this
dengan cara yang tidak mengharapkan kode di sekitarnya memiliki
pada struktur tertentu. Pengecualian untuk aturan ini adalah ES5
Fungsi panah.
this
dalam fungsi panah
Di fungsi panah,
this
me-resolve ke binding di
lingkungan yang inklusif secara leksik. Hal ini berarti bahwa
this
dalam fungsi panah mengacu pada nilai this
dalam atribut
konteks yang paling dekat:
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 {...}
Pada contoh sebelumnya, myObject.myMethod()
mencatat myObject
sebagai objek
yang "memiliki" metode tersebut, tetapi myObject.myArrowFunction()
akan menampilkan globalThis
(atau undefined
), karena instance this
di dalam fungsi panah
merujuk pada ruang
lingkup tertinggi.
Pada contoh berikut, myEnclosingMethod
membuat fungsi panah di
yang di dalamnya saat dieksekusi. Instance this
di dalam
fungsi panah sekarang merujuk pada nilai this
di dalam
lingkungan, yakni metode yang
berisi fungsi panah tersebut. Karena
nilai this
di dalam myEnclosingMethod
mengacu pada myObject
, setelah Anda
menentukan fungsi panah, this
di dalam fungsi panah juga mengacu pada
myObject
:
let myObject = {
myMethod() { console.log( this ); },
myEnclosingMethod: function () {
this.myArrowFunction = () => { console.log(this) };
}
};
myObject.myEnclosingMethod();
myObject.myArrowFunction();
> Object { myMethod: myMethod(), myArrowFunction: myArrowFunction() }
Binding eksplisit
Binding implisit menangani sebagian besar kasus penggunaan untuk menggunakan this
. Namun, Anda
terkadang mungkin memerlukan nilai this
untuk merepresentasikan eksekusi spesifik
konteks, alih-alih konteks yang diasumsikan. Sebuah ilustrasi, jika sedikit sudah usang,
contohnya adalah bekerja dengan this
dalam fungsi callback setTimeout
,
karena callback ini memiliki konteks eksekusi unik:
var myObject = {
myString: "This is my string.",
myMethod() {
console.log( this.myString );
}
};
myObject.myMethod();
> "This is my string."
setTimeout( myObject.myMethod, 100 );
> undefined
Meskipun kekurangan spesifik setTimeout
ini telah diatasi oleh
fitur lain, masalah serupa seperti "kehilangan" this
telah ditangani sebelumnya
dengan membuat referensi eksplisit ke nilai this
dalam cakupan
konteks yang diinginkan. Terkadang Anda mungkin melihat instance this
ditetapkan
ke variabel menggunakan ID seperti that
, self
, atau _this
di versi lama
codebase. Ini adalah konvensi pengenal umum untuk variabel yang berisi
melewati this
nilai.
Saat Anda memanggil fungsi menggunakan metode call()
, bind()
, atau apply()
,
this
secara eksplisit merujuk ke objek yang dipanggil:
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."
Binding eksplisit menggantikan nilai this
yang disediakan oleh binding implisit.
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."
Jika fungsi dipanggil dengan cara yang akan menetapkan nilai this
ke
undefined
atau null
, nilai tersebut akan diganti dengan globalThis
dari luar strict
mode:
let myFunction = function() {
console.log( this );
}
myFunction.call( null );
> Window {...}
Demikian pula, jika fungsi dipanggil dengan cara yang akan memberikan primitif kepada this
nilai tersebut, nilai tersebut diganti dengan
objek wrapper nilai primitif
di luar mode ketat:
let myFunction = function() {
console.log( this );
}
let myNumber = 10;
myFunction.call( myNumber );
> Number { 10 }
Dalam mode ketat, nilai this
yang diteruskan tidak diberlakukan ke objek dengan cara apa pun,
meskipun itu adalah nilai primitif, null
, atau undefined
:
"use strict";
let myFunction = function() {
console.log( this );
}
let myNumber = 10;
myFunction.call( myNumber );
> 10
myFunction.call( null );
> null
Binding new
Saat class digunakan sebagai konstruktor menggunakan
Kata kunci new
, this
merujuk pada instance yang baru dibuat:
class MyClass {
myString;
constructor() {
this.myString = "My string.";
}
logThis() {
console.log( this );
}
}
const thisClass = new MyClass();
thisClass.logThis();
> Object { myString: "My string." }
Demikian pula, nilai this
di dalam fungsi konstruktor yang dipanggil menggunakan new
mengacu pada objek yang dibuat:
function MyFunction() {
this.myString = "My string.";
this.logThis = function() {
console.log( this );
}
}
const myObject = new MyFunction();
myObject.logThis();
> Object { myString: "My string.", logThis: logThis() }
Binding pengendali peristiwa
Dalam konteks pengendali peristiwa, nilai this
merujuk ke objek yang
memanggilnya. Di dalam fungsi callback pengendali peristiwa, itu berarti this
merujuk ke elemen yang terkait dengan pengendali:
let button = document.querySelector( "button" );
button.addEventListener( "click", function( event ) { console.log( this ); } );
Saat pengguna berinteraksi dengan button
di cuplikan sebelumnya, hasilnya adalah
objek elemen yang berisi <button>
itu sendiri:
> Button {}
Saat fungsi panah digunakan sebagai callback pemroses peristiwa, nilai
this
kembali disediakan oleh konteks eksekusi yang mencakup terdekat. Di bagian atas
Ini berarti this
di dalam fungsi callback pengendali peristiwa
globalThis
(atau undefined
, dalam mode ketat):
let button = document.querySelector( "button" );
button.addEventListener( "click", ( event ) => { console.log( this ); } );
> undefined
Seperti objek lainnya, saat Anda menggunakan call()
, bind()
, atau apply()
untuk mereferensikan fungsi callback dari pemroses peristiwa, this
merujuk ke objek secara eksplisit:
let button = document.querySelector( "button" );
let myObject = {
"myValue" : true
};
function handleClick() {
console.log( this );
}
button.addEventListener( "click", handleClick.bind( myObject ) );
> Object { myValue: true }
Menguji pemahaman Anda
Apa objek global untuk skrip yang berjalan di browser web
yang dirujuk this
saat digunakan di luar fungsi atau
konteks objek?
browser
undefined
window