Masukkan Password
54 Fungsi Panah & Variabel Ini
Lecture ini sangat penting, karena mulai dari sini kamu akan melihat kenapa this adalah salah satu bagian JavaScript yang sering membingungkanβterutama ketika kita mencampur regular function, arrow function, dan method object.
Kunci terbesar lecture ini sebenarnya hanya satu:
Regular function punya
thissendiri, sedangkan arrow function tidak punyathissendiri. Arrow function mengambilthisdari scope di luarnya.
Mari kita bedah pelan-pelan.
1. Review singkat: this di dalam method
Di lecture sebelumnya kita belajar:
const person = {
firstName: "John",
birthYear: 1990,
calculateAge: function () {
return 2024 - this.birthYear;
}
};
Kalau kita panggil:
person.calculateAge();
Maka:
this
mengarah ke:
person
Sehingga:
this.birthYear
sama dengan:
person.birthYear
yaitu:
1990
Jadi:
person.calculateAge()
β
method dipanggil
β
this
β
person
Ini konsep dasar yang harus kamu pegang sebelum masuk ke masalah berikutnya.
2. Masalah utama lecture ini
Sekarang kita punya:
const person = {
firstName: "John",
birthYear: 1990,
calculateAge: function () {
console.log(this);
return 2024 - this.birthYear;
}
};
Saat:
person.calculateAge();
this β person.
Sampai sini aman.
Tapi bagaimana kalau di dalam method tersebut kita membuat function lain?
Misalnya:
const person = {
firstName: "John",
birthYear: 1990,
calculateAge: function () {
function greet() {
console.log(this.firstName);
}
greet();
return 2024 - this.birthYear;
}
};
Nah, di sinilah masalah dimulai.
3. Jangan berpikir this mengikuti tempat function dibuat
Ini kesalahan yang sangat umum.
Kita mungkin berpikir:
“
greet()dibuat di dalamcalculateAge(), berartithisdigreet()pasti sama denganthisdicalculateAge().”
Salah.
Untuk regular function, this tidak ditentukan hanya berdasarkan di mana function tersebut dibuat.
Yang penting adalah bagaimana function tersebut dipanggil.
Perhatikan:
greet();
Kita memanggilnya seperti function biasa.
Bukan:
person.greet();
Jadi greet() adalah regular function call.
4. Regular function punya aturan this sendiri
Untuk regular function:
Non-strict mode
function greet() {
console.log(this);
}
greet();
Di browser, secara umum:
this β window
Strict mode
"use strict";
function greet() {
console.log(this);
}
greet();
Hasil:
this β undefined
Jadi:
| Situasi | this |
|---|---|
| Regular function, non-strict | window |
| Regular function, strict | undefined |
Ini berlaku meskipun function tersebut dibuat di dalam method.
5. Contoh masalahnya
Misalnya:
const person = {
firstName: "John",
birthYear: 1990,
calculateAge: function () {
function greet() {
console.log(this.firstName);
}
greet();
return 2024 - this.birthYear;
}
};
Kita panggil:
person.calculateAge();
Pada calculateAge:
this
β person.
Tetapi ketika:
greet();
dipanggil:
greet()
adalah regular function call.
Maka this di dalam greet() tidak otomatis menjadi person.
Dalam non-strict mode:
this β window
Dalam strict mode:
this β undefined
6. Ini konsep yang sangat penting: “di mana dibuat” vs “bagaimana dipanggil”
Bandingkan:
const person = {
greet: function () {
console.log(this);
}
};
person.greet();
Di sini:
person.greet()
β
dipanggil sebagai method
β
this β person
Sedangkan:
const person = {
calculateAge: function () {
function greet() {
console.log(this);
}
greet();
}
};
Di sini:
greet()
β
regular function call
β
this β window / undefined
Jadi jangan berpikir:
“Function berada di dalam object, berarti
thispasti object.”
Tidak.
Yang harus ditanyakan:
Function ini dipanggil dengan cara apa?
7. Lalu bagaimana dengan arrow function?
Nah, ini alasan arrow function menjadi sangat menarik.
Arrow function:
const greet = () => {
console.log(this);
};
tidak mempunyai this sendiri.
Ini aturan penting:
Arrow function mengambil
thisdari lexical/parent scope-nya.
Bahasa sederhananya:
Arrow function berkata: “Saya tidak punya
thissendiri. Saya akan menggunakanthismilik lingkungan di luar saya.”
8. Contoh arrow function di dalam method
Sekarang:
const person = {
firstName: "John",
birthYear: 1990,
calculateAge: function () {
const greet = () => {
console.log(this.firstName);
};
greet();
return 2024 - this.birthYear;
}
};
Lalu:
person.calculateAge();
Mari kita telusuri.
Pertama:
person.calculateAge();
calculateAge adalah method.
Maka:
this
di calculateAge:
this β person
Kemudian kita punya:
const greet = () => {
console.log(this.firstName);
};
greet adalah arrow function.
Arrow function tidak punya this sendiri.
Jadi dia bertanya:
“Siapa
thisdi parent scope saya?”
Parent-nya adalah calculateAge.
Di calculateAge:
this β person
Maka arrow function ikut menggunakan:
this β person
Akibatnya:
this.firstName
menjadi:
person.firstName
dan hasilnya:
John
9. Visualisasi konsepnya
Ini sangat penting untuk dihafalkan:
person.calculateAge()
β
calculateAge
β
this β person
β
greet()
β
arrow function
β
tidak punya this sendiri
β
ambil this dari parent
β
this β person
Sedangkan regular function:
person.calculateAge()
β
calculateAge
β
this β person
β
greet()
β
regular function
β
punya this sendiri
β
regular function call
β
this β window / undefined
10. Kenapa lecture membuat contoh greetUser?
Lecture membuat sesuatu seperti:
const person = {
firstName: "John",
birthYear: 1990,
greetUser: () => {
console.log("Good morning " + this.firstName);
}
};
Kemudian:
person.greetUser();
Mungkin kita berpikir:
“Karena
greetUser()dipanggil dariperson, bukankahthisharusperson?”
Tidak.
Karena greetUser adalah arrow function.
Arrow function tidak mendapatkan this dari:
person.greetUser()
Dia mengambil this dari scope tempat arrow function dibuat.
11. Ini bagian yang sangat penting: object {} bukan otomatis scope
Lecture juga menyinggung sesuatu yang cukup membingungkan.
Misalnya:
const person = {
firstName: "John",
greetUser: () => {
console.log(this.firstName);
}
};
Kamu mungkin melihat:
{
...
}
dan berpikir:
“
thisdi dalam sini pasti milik objectperson.”
Tidak.
Kurung kurawal object literal:
{
firstName: "John"
}
bukan berarti kita membuat lexical scope seperti:
if (...) {
...
}
atau:
function test() {
...
}
Jadi arrow function di property object tidak otomatis mendapatkan this dari object tersebut.
12. Ini kesalahan yang sangat sering terjadi
Banyak beginner menulis:
const person = {
name: "John",
greet: () => {
console.log(this.name);
}
};
dan berharap:
John
Tetapi biasanya tidak begitu.
Karena:
greet β arrow function
β
tidak punya this sendiri
β
ambil this dari outer scope
Bukan:
greet β person
13. Kalau ingin this menunjuk ke object, gunakan regular function
Misalnya:
const person = {
name: "John",
greet: function () {
console.log(this.name);
}
};
Kemudian:
person.greet();
Sekarang:
person.greet()
β
regular function sebagai method
β
this β person
β
this.name
β
John
Jadi untuk method object yang membutuhkan this, regular function biasanya lebih tepat.
14. Contoh perbandingan yang sangat jelas
Regular function
const person = {
name: "John",
greet: function () {
console.log(this.name);
}
};
person.greet();
Hasil:
John
Karena:
this β person
Arrow function
const person = {
name: "John",
greet: () => {
console.log(this.name);
}
};
person.greet();
this bukan person.
Karena arrow function mengambil this dari outer scope.
15. Solusi pertama lecture: simpan this ke variable
Sebelum arrow function populer, salah satu pola yang sering digunakan adalah:
const person = {
firstName: "John",
calculateAge: function () {
const self = this;
function greet() {
console.log("Good morning " + self.firstName);
}
greet();
}
};
Perhatikan:
const self = this;
Pada saat baris ini dijalankan:
this
adalah:
person
Maka:
self
menjadi referensi ke:
person
Kemudian di dalam greet():
self.firstName
tetap mengarah ke:
person.firstName
Hasil:
Good morning John
16. Kenapa teknik self = this bekerja?
Urutannya:
person.calculateAge()
β
this β person
β
self = this
β
self β person
β
greet()
β
regular function
β
this β window / undefined
Tapi kita tidak menggunakan this di dalam greet.
Kita menggunakan:
self
Dan self tetap menyimpan referensi ke person.
17. Solusi kedua: gunakan arrow function
Cara modern:
const person = {
firstName: "John",
calculateAge: function () {
const greet = () => {
console.log("Good morning " + this.firstName);
};
greet();
}
};
Lebih simpel.
Tidak perlu:
const self = this;
Karena arrow function otomatis mengambil this dari parent scope.
calculateAge
β
this β person
β
arrow greet
β
ambil this parent
β
this β person
Inilah salah satu alasan arrow function sangat berguna.
18. Hubungan dengan lecture sebelumnya: event handler
Ini juga nyambung dengan lecture sebelumnya.
Misalnya:
const button = document.querySelector("#example-button");
button.addEventListener("click", function () {
console.log(this);
});
Ketika button diklik:
this β button
Karena regular function digunakan sebagai event handler.
Tetapi kalau:
button.addEventListener("click", () => {
console.log(this);
});
Sekarang arrow function tidak memiliki this sendiri.
Jadi dia mengambil this dari outer scope.
Dalam konteks kode browser biasa, itu bisa menjadi window atau mengikuti konteks lexical tempat arrow dibuat.
19. Jadi jangan tertukar antara dua jenis function
Regular function
function () {
console.log(this);
}
Memiliki this sendiri.
Nilai this ditentukan berdasarkan cara function dipanggil.
Arrow function
() => {
console.log(this);
}
Tidak memiliki this sendiri.
this diambil dari outer lexical scope.
20. Tabel paling penting dari lecture ini
| Situasi | Regular Function | Arrow Function |
|---|---|---|
Punya this sendiri? | β Ya | β Tidak |
this ditentukan dari cara dipanggil? | β Ya | β Tidak |
Mengambil this dari outer scope? | β | β |
| Sebagai method object | Biasanya cocok jika butuh this | Biasanya jangan jika berharap this = object |
| Nested function di dalam method | this berubah menjadi aturan regular function | Bisa mempertahankan this parent |
| Event handler | this biasanya element | Tidak otomatis element |
21. Satu kalimat yang wajib kamu ingat
Kalau hanya mau mengingat satu hal dari lecture ini:
Regular function punya
thissendiri. Arrow function tidak punyathissendiri.
Dan untuk arrow function:
“Saya pinjam
thisdari luar saya.”
22. Bedakan “scope” dengan “this”
Ini juga penting karena sebelumnya kamu sudah belajar scope.
scope dan this bukan hal yang sama.
Scope menjawab:
“Variable mana yang bisa saya akses?”
Contoh:
const name = "John";
function test() {
console.log(name);
}
test() bisa mengakses name karena lexical scope.
Sedangkan this menjawab secara sederhana:
“Object/context mana yang direferensikan oleh
this?”
Jadi:
Scope
β
berhubungan dengan akses identifier/variable
this
β
berhubungan dengan binding/context this
Jangan menganggap:
parent scope = object
Itu tidak selalu benar.
23. Contoh yang menggabungkan semuanya
Perhatikan:
const person = {
firstName: "John",
calculateAge: function () {
console.log(this.firstName);
const greet = () => {
console.log(this.firstName);
};
greet();
}
};
Panggil:
person.calculateAge();
Langkah 1
person.calculateAge()
Karena calculateAge dipanggil sebagai method:
this β person
Langkah 2
console.log(this.firstName);
Menjadi:
console.log(person.firstName);
Hasil:
John
Langkah 3
const greet = () => {
console.log(this.firstName);
};
Arrow function tidak punya this.
Langkah 4
greet();
Arrow function mencari this dari parent lexical scope.
Parent-nya adalah:
calculateAge
Di sana:
this β person
Jadi:
this β person
Hasil kedua:
John
Output:
John
John
24. Tapi kalau greet adalah regular function?
const person = {
firstName: "John",
calculateAge: function () {
console.log(this.firstName);
function greet() {
console.log(this.firstName);
}
greet();
}
};
Saat:
person.calculateAge();
Di calculateAge:
this β person
Tetapi:
greet();
adalah regular function call.
Jadi this di greet tidak mewarisi this dari calculateAge.
Dalam strict mode:
this β undefined
Dalam non-strict browser:
this β window
Maka:
this.firstName
bisa menghasilkan error dalam strict mode atau undefined tergantung kondisi global.
25. Kenapa arrow function dibuat seperti ini?
Salah satu kegunaan besar arrow function adalah menangani kasus seperti:
method β nested function
Kita ingin nested function tetap menggunakan this dari method.
Dengan regular function:
function greet() {
console.log(this.name);
}
this bisa berubah.
Dengan arrow function:
const greet = () => {
console.log(this.name);
};
this dipertahankan dari outer scope.
Jadi sangat berguna ketika kita ingin:
method
β
this = object
β
nested arrow function
β
tetap menggunakan this = object
26. Hubungan dengan callback
Ini akan sering kamu temui nanti.
Contohnya:
const person = {
name: "John",
greet: function () {
setTimeout(() => {
console.log(this.name);
}, 1000);
}
};
Ketika:
person.greet();
greet memiliki:
this β person
Callback:
() => {
console.log(this.name);
}
adalah arrow function.
Dia mengambil this dari outer scope.
Jadi:
this β person
dan setelah 1 detik:
John
Ini adalah pola yang sangat umum dalam JavaScript modern.
27. Kapan sebaiknya menggunakan regular function?
Gunakan regular function ketika kamu memang membutuhkan this yang ditentukan dari cara function dipanggil.
Contoh method object:
const user = {
name: "Budi",
sayHello: function () {
console.log(this.name);
}
};
Ini masuk akal karena kita ingin:
user.sayHello();
menghasilkan:
Budi
28. Kapan arrow function cocok?
Arrow function sangat cocok ketika kamu ingin function menggunakan this dari outer scope.
Misalnya nested callback:
const user = {
name: "Budi",
sayHello: function () {
setTimeout(() => {
console.log(this.name);
}, 1000);
}
};
Di sini arrow function sangat berguna.
29. Jangan gunakan pola ini jika mengharapkan this = object
Hindari:
const user = {
name: "Budi",
sayHello: () => {
console.log(this.name);
}
};
Kalau tujuanmu adalah:
user.sayHello();
dan berharap:
Budi
Arrow function bukan pilihan yang tepat untuk method seperti ini.
Lebih aman:
const user = {
name: "Budi",
sayHello: function () {
console.log(this.name);
}
};
30. Cheat sheet this
Ini bagian yang bagus untuk kamu screenshot/simpan.
THIS
β
ββββββββββββββββΌβββββββββββββββ
β β β
Global Regular Method
scope function call
β β β
browser: non-strict: object yang
window window memanggil
strict: method
undefined
β
β
βββββββββββββββββββββββββββββββββ
β β
Arrow function Event handler
β β
tidak punya this regular function:
sendiri element/event target
β
ambil this dari arrow function:
outer scope ambil this dari
outer scope
31. Lima poin yang harus kamu kuasai
Lecture memberikan lima aturan besar. Saya sederhanakan:
β Global scope
console.log(this);
Di browser klasik:
this β window
β‘ Regular function
function test() {
console.log(this);
}
Non-strict:
this β window
Strict:
this β undefined
β’ Method
const person = {
name: "John",
greet: function () {
console.log(this);
}
};
person.greet();
this β person
β£ Arrow function
const greet = () => {
console.log(this);
};
arrow function
β
tidak punya this sendiri
β
ambil this dari outer scope
β€ Event handler
Regular function:
button.addEventListener("click", function () {
console.log(this);
});
Biasanya:
this β button
Arrow function:
button.addEventListener("click", () => {
console.log(this);
});
this β outer scope
bukan otomatis:
this β button
32. Hubungan dengan lecture arrow function sebelumnya
Sebelumnya kamu belajar:
const greet = (name) => {
console.log("Hello " + name);
};
Kita sekarang menambahkan satu hal penting:
Arrow function bukan hanya syntax yang lebih pendek.
Memang benar:
function (name) {
console.log(name);
}
bisa ditulis:
(name) => {
console.log(name);
}
Tetapi arrow function juga memiliki perbedaan perilaku, terutama:
this
arguments
constructor behavior
Untuk saat ini, yang paling penting:
Arrow function tidak memiliki
thissendiri.
33. Kesalahan pemahaman yang paling sering terjadi
β Salah
“
thisselalu menunjuk ke object tempat function dibuat.”
β Benar
Untuk regular function, this bergantung pada cara function dipanggil.
β Salah
“Kalau function berada di dalam object,
thispasti object tersebut.”
β Benar
Tidak selalu.
Terutama arrow function:
const person = {
greet: () => {
console.log(this);
}
};
Arrow function tidak mengambil this dari object.
β Salah
“Arrow function punya
this, tapi nilainya berbeda.”
β Lebih tepat
Arrow function tidak membuat this baru.
Ia menggunakan this dari outer lexical scope.
β Salah
“Function yang berada di dalam method otomatis mewarisi
thismethod.”
β Benar
Regular function tidak otomatis mewarisi this.
Arrow function bisa mempertahankan this dari outer scope.
34. Mental model paling sederhana
Bayangkan this seperti orang yang sedang kamu tunjuk.
Regular function
Regular function berkata:
“Aku punya aturan sendiri. Lihat bagaimana aku dipanggil untuk menentukan siapa yang aku tunjuk.”
Arrow function
Arrow function berkata:
“Aku tidak menentukan sendiri. Aku ikut menunjuk orang yang ditunjuk oleh lingkungan di luar aku.”
Jadi:
Regular Function
"Siapa yang memanggil saya?"
β
this
Sedangkan:
Arrow Function
"Siapa this di luar saya?"
β
ambil this tersebut
35. Ringkasan super singkat
const person = {
name: "John",
regular: function () {
console.log(this.name);
},
arrow: () => {
console.log(this.name);
}
};
Untuk:
person.regular();
regular function
β
this β person
β
John
Untuk:
person.arrow();
arrow function
β
tidak punya this sendiri
β
ambil this dari outer scope
β
bukan person
π§ Inti yang harus benar-benar kamu ingat
Kalau saya ringkas lecture ini menjadi 3 kalimat:
1. Regular function memiliki
thissendiri, dan nilaithisditentukan dari cara function dipanggil.
2. Arrow function tidak memiliki
thissendiri; ia mengambilthisdari lexical/outer scope.
3. Karena itu, gunakan regular function untuk method yang memang membutuhkan
thisdari object, sedangkan arrow function sangat berguna untuk nested function/callback yang ingin mempertahankanthisdari luar.
Dan satu pola yang sangat penting untuk kamu hafalkan:
OBJECT METHOD
β
β regular function
β
this β object
OBJECT METHOD
β
β nested arrow function
β
arrow tidak punya this
β
ambil this dari method
β
this β object
Sedangkan:
OBJECT METHOD
β
β nested regular function
β
punya this sendiri
β
dipanggil sebagai function biasa
β
non-strict β window
strict β undefined
Ini adalah inti dari seluruh lecture. Kalau bagian ini sudah terasa jelas, lecture-lecture berikutnya tentang this, call(), apply(), bind(), dan arrow function akan jauh lebih mudah dipahami.