Kata kunci ini

Kata kunci this mengacu pada nilai objek yang terikat dengan fungsi pada saat panggilannya, yang berarti nilainya berbeda bergantung pada apakah fungsi dipanggil sebagai metode, sebagai fungsi mandiri, atau sebagai konstruktor.

Saat dipanggil, fungsi akan membuat instance kata kunci this di balik layar sebagai referensi ke objek yang berisi fungsi tersebut, yang memberikan akses ke properti dan metode yang ditentukan bersamanya dari dalam cakupannya. Penggunaan this mirip dengan beberapa cara penggunaan variabel yang dideklarasikan dengan const. Seperti konstanta, this tidak dapat dihapus dan nilainya tidak dapat ditetapkan ulang, tetapi metode dan properti objek yang dimuat kata kunci this dapat diubah.

Binding global

Di luar fungsi atau konteks objek, this merujuk ke properti globalThis, yang merupakan referensi ke objek global di sebagian besar lingkungan JavaScript. Dalam konteks skrip yang berjalan di browser 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 ke objek global di dalam fungsi mandiri, karena Window induk adalah objek yang secara efektif "memiliki" fungsi tersebut.

function myFunction() {
    console.log( this );
}
myFunction();
> Window {...}

(function() {
    console.log( this );
}());
> Window {...}

Saat menggunakan mode ketat, this memiliki nilai undefined di dalam fungsi mandiri:

(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 fungsi dipanggil sebagai metode objek, instance this di dalam metode tersebut merujuk ke objek yang berisi metode, yang memberikan akses ke metode dan properti yang berada di sampingnya:

let myObject = {
    myValue: "This is my string.",
    myMethod() {
            console.log( this.myValue );
    }
};

myObject.myMethod();
> "This is my string."

Tampaknya nilai this bergantung pada cara fungsi dan objek penyertanya ditentukan. Sebagai gantinya, konteks untuk nilai this adalah konteks eksekusi saat ini. Dalam hal ini, konteks eksekusi adalah bahwa objek myObject memanggil metode myMethod, sehingga myObject adalah nilai untuk this. Hal ini mungkin tampak seperti teknis dalam konteks contoh sebelumnya, tetapi untuk penggunaan this yang lebih canggih, ini adalah perbedaan penting yang harus diingat.

Secara umum, gunakan this dengan cara yang tidak mengharapkan kode di sekitarnya memiliki struktur tertentu. Pengecualian untuk aturan ini adalah Fungsi panah ES5.

this dalam fungsi panah

Dalam fungsi panah, this di-resolve ke binding dalam lingkungan yang melingkupi secara leksik. Artinya, this dalam fungsi panah mengacu pada nilai this dalam konteks penutup terdekat fungsi tersebut:

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() menampilkan globalThis (atau undefined), karena instance this di dalam fungsi panah sebenarnya merujuk ke cakupan terluas yang mencakup.

Dalam contoh berikut, myEnclosingMethod membuat fungsi panah pada objek yang berisinya saat dieksekusi. Instance this di dalam fungsi panah kini merujuk ke nilai this di dalam lingkungan penyertaan, yang merupakan 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 mewakili konteks eksekusi tertentu, bukan konteks yang diasumsikan. Contoh ilustrasi, jika sedikit usang, bekerja dengan this dalam fungsi callback setTimeout, karena callback ini memiliki konteks eksekusi yang 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 terkait "kehilangan" this sebelumnya telah diatasi dengan membuat referensi eksplisit ke nilai this dalam cakupan konteks yang diinginkan. Anda mungkin sesekali melihat instance this ditetapkan ke variabel menggunakan ID seperti that, self, atau _this di codebase lama. Ini adalah konvensi ID umum untuk variabel yang berisi nilai this yang diteruskan.

Saat Anda memanggil fungsi menggunakan metode call(), bind(), atau apply(), this secara eksplisit mereferensikan 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 mengganti 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 di luar mode ketat:

let myFunction = function() {
    console.log( this );
}

myFunction.call( null );
> Window {...}

Demikian pula, jika fungsi dipanggil dengan cara yang akan memberikan nilai primitif ke this, nilai tersebut akan 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 dikonversi menjadi objek dengan cara apa pun, meskipun nilai tersebut berupa 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 ke 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 merujuk ke objek yang sedang 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 mereferensikan objek yang memanggilnya. Di dalam fungsi callback pengendali peristiwa, artinya this mereferensikan 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 akan disediakan lagi oleh konteks eksekusi yang paling dekat. Pada tingkat tertinggi, artinya this di dalam fungsi callback pengendali peristiwa adalah globalThis:

let button = document.querySelector( "button" );

button.addEventListener( "click", ( event ) => { console.log( this ); } );
> undefined

Seperti objek lainnya, saat Anda menggunakan metode call(), bind(), atau apply() untuk mereferensikan fungsi callback pemroses peristiwa, this akan mereferensikan 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 }

Memeriksa pemahaman Anda

Untuk skrip yang berjalan di browser web, apa objek global yang dirujuk this saat digunakan di luar fungsi atau konteks objek?

Objek window
Objek browser
Objek undefined