Kata kunci ini

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?

Objek window
Objek browser
Objek undefined