Masukkan Password
79 Saat Dekorator Dieksekusi
Lecture ini membahas satu hal yang sangat penting dalam memahami decorators:
Kapan sebenarnya decorator dijalankan?
Ini penting karena sering muncul salah paham seperti:
“Decorator baru dijalankan ketika object dibuat?”
Jawabannya, dalam konteks legacy TypeScript decorators yang sedang diajarkan di course ini: tidak.
Decorator diproses ketika definisi class sedang diproses, bukan ketika kita membuat instance.
Mari kita bahas pelan-pelan.
1. Gambaran besar lecture
Misalnya kita punya class:
@ClassDecorator
class Person {
@PropertyDecorator
name: string;
@MethodDecorator
calculateAge(
@ParameterDecorator dateOfBirth: string
) {
}
}
Di sini ada beberapa decorator:
Person
│
├── @ClassDecorator
│
├── name
│ └── @PropertyDecorator
│
└── calculateAge()
│
├── @MethodDecorator
│
└── dateOfBirth
└── @ParameterDecorator
Pertanyaannya:
Kapan semua decorator ini dijalankan?
Jawabannya:
Ketika JavaScript/TypeScript memproses definisi class tersebut.
Bukan ketika:
const person = new Person();
2. Decorator tidak menunggu instance dibuat
Misalnya kita punya:
function Logger(target: any) {
console.log("Decorator called");
}
@Logger
class Person {
name: string;
}
Kemudian kita tidak melakukan apa-apa lagi.
Tidak ada:
const person = new Person();
Tetapi decorator tetap akan dijalankan ketika class definition diproses.
Secara sederhana:
Program dijalankan
↓
JavaScript menemukan class Person
↓
@Logger ditemukan
↓
Logger dijalankan
↓
class Person selesai diproses
Jadi:
@Logger
class Person {}
sudah cukup untuk membuat decorator diproses.
3. Lalu kapan method-nya dijalankan?
Nah, ini berbeda.
Misalnya:
@Logger
class Person {
@MethodLogger
calculateAge() {
console.log("Calculating...");
}
}
Ada dua hal yang berbeda:
Decorator dijalankan
ketika class definition diproses:
Person class ditemukan
↓
MethodLogger diproses
Method dijalankan
ketika kita benar-benar memanggil:
const person = new Person();
person.calculateAge();
Jadi jangan menyamakan:
decorator execution
dengan:
method execution
4. Analogi sederhana: dekorasi rumah
Bayangkan kamu sedang membangun rumah.
Rumah
│
├── pintu
├── jendela
└── kamar
Decorator adalah seperti proses memasang label/dekorasi ketika rumah sedang disiapkan.
Misalnya:
@SecurityCamera
class House {}
Saat rumah didefinisikan/dibangun, security camera dipasang.
Bukan menunggu seseorang masuk ke rumah.
Begitu juga decorator.
class Person
↓
decorator diproses
↓
class siap digunakan
Kemudian nanti:
new Person()
adalah seperti seseorang masuk ke rumah.
Itu kejadian berbeda.
5. “Compile time” vs “runtime”
Lecture mengatakan:
decorators get executed at compile time and not at runtime.
Untuk memahami course ini, kamu perlu hati-hati dengan istilah ini.
Secara praktis, yang ingin lecturer tekankan adalah:
Decorator diproses ketika class definition dievaluasi/didefinisikan, bukan ketika instance dibuat atau method dipanggil.
TypeScript sendiri melakukan transpilation/compilation terlebih dahulu, dan decorator code yang dihasilkan kemudian dieksekusi oleh JavaScript saat program berjalan.
Jadi untuk mental model yang lebih aman:
TypeScript source
↓
compile/transpile
↓
JavaScript
↓
class definition dievaluasi
↓
decorator dijalankan
↓
new Person()
↓
method dipanggil
Jadi jangan terlalu terpaku pada kalimat “compile time” sebagai istilah teknis. Yang paling penting adalah:
Decorator tidak menunggu
new Person()dan tidak menungguperson.calculateAge().
6. Contoh yang sangat jelas
Misalnya:
function Logger(target: any) {
console.log("Logger decorator executed");
}
@Logger
class Person {
constructor() {
console.log("Person constructor executed");
}
}
Kalau kita membuat:
const person = new Person();
urutan sederhananya:
Logger decorator executed
↓
Person constructor executed
Bukan:
new Person()
↓
Logger decorator
↓
constructor
Decorator sudah diproses sebelum instance dibuat.
7. Bahkan tanpa new Person(), decorator tetap diproses
Misalnya:
function Logger(target: any) {
console.log("Decorator executed");
}
@Logger
class Person {
}
Tidak ada:
new Person();
Tetapi:
Decorator executed
tetap muncul.
Ini adalah salah satu poin utama lecture.
8. Sekarang masuk ke execution order
Bagian kedua lecture adalah tentang:
Kalau ada banyak decorator, mana yang dijalankan dulu?
Nah, di sini kita harus hati-hati karena urutannya berbeda tergantung decorator dipasang di mana.
Lecture memberikan aturan:
Class → bottom to top
Property → top to bottom
Method → top to bottom
Parameter → left to right
Mari kita bahas satu per satu.
9. Multiple decorators pada class
Misalnya:
@First
@Second
@Third
class Person {
}
Urutannya adalah:
Third
↓
Second
↓
First
Jadi decorator paling bawah dijalankan terlebih dahulu.
Visual:
@First
@Second
@Third
class Person
↓
↓
Third
↓
Second
↓
First
Ingat:
Class decorator → bottom to top.
10. Kenapa terasa terbalik?
Karena kita membaca source code dari atas:
First
Second
Third
tetapi execution-nya:
Third
Second
First
Makanya ini sering membingungkan.
Gunakan mnemonic:
Class: dari bawah naik ke atas.
11. Contoh menggunakan console.log
Misalnya:
function First(target: any) {
console.log("First");
}
function Second(target: any) {
console.log("Second");
}
function Third(target: any) {
console.log("Third");
}
@First
@Second
@Third
class Person {
}
Output-nya secara konsep:
Third
Second
First
Bukan:
First
Second
Third
12. Property decorator berbeda
Sekarang misalnya:
class Person {
@First
@Second
@Third
name: string;
}
Untuk property decorator, lecture menjelaskan execution order:
top to bottom
Jadi:
First
↓
Second
↓
Third
Output:
First
Second
Third
13. Jadi class dan property berbeda
Ini penting sekali:
CLASS
@First
@Second
@Third
class Person
Execution:
Third → Second → First
Sedangkan:
PROPERTY
@First
@Second
@Third
name: string
Execution:
First → Second → Third
Jadi jangan menggunakan satu aturan untuk semuanya.
14. Method decorator
Untuk method juga, menurut lecture:
top to bottom
Contoh:
class Person {
@First
@Second
@Third
calculateAge() {
}
}
Urutannya:
First
↓
Second
↓
Third
Jadi:
Method decorator
→ top to bottom
15. Parameter decorator
Untuk parameter, lecture menjelaskan:
left to right
Misalnya kita memiliki beberapa decorator pada parameter:
calculateAge(
@First @Second @Third dateOfBirth: string
) {
}
Urutannya:
First → Second → Third
Karena decorator dibaca dari kiri ke kanan.
Jadi:
Parameter decorator
→ left to right
16. Ringkasan execution order
Ini tabel yang sebaiknya kamu hafalkan:
| Tempat decorator | Execution order |
|---|---|
| Class | Bottom → Top |
| Property | Top → Bottom |
| Method | Top → Bottom |
| Parameter | Left → Right |
Mnemonic:
CLASS → BOTTOM → TOP
PROPERTY → TOP → BOTTOM
METHOD → TOP → BOTTOM
PARAMETER → LEFT → RIGHT
17. Hubungkan dengan lecture sebelumnya
Sebelumnya kita belajar bahwa untuk class:
@logger()
@template()
class Person {}
ada konsep:
Decorator factory dieksekusi top-to-bottom, kemudian decorator yang dihasilkan diaplikasikan bottom-to-top.
Ini agak berbeda dengan sekadar mengatakan:
“decorator dieksekusi bottom-to-top.”
Kenapa?
Karena ada dua tahap.
Misalnya:
@First()
@Second()
@Third()
class Person {}
Secara konseptual:
Tahap 1 — factory dipanggil
First()
Second()
Third()
dari:
Top → Bottom
Tahap 2 — decorator diterapkan
Third
Second
First
dari:
Bottom → Top
Jadi kalau nanti kamu melihat decorator factory, jangan lupa ada dua proses.
18. Jangan mencampur “execution order” dengan “method call order”
Ini juga penting.
Misalnya:
function Logger(target: any) {
console.log("Logger decorator");
}
class Person {
@Logger
calculateAge() {
console.log("calculateAge method");
}
}
Saat program memproses class:
Logger decorator
muncul.
Kemudian kalau:
const person = new Person();
person.calculateAge();
baru:
calculateAge method
muncul.
Jadi:
Decorator execution
↓
class siap
↓
instance dibuat
↓
method dipanggil
↓
method execution
19. Apakah constructor menjalankan decorator?
Tidak.
Misalnya:
class Person {
constructor() {
console.log("Constructor");
}
@Logger
calculateAge() {
}
}
Decorator @Logger tidak menunggu constructor.
Jadi:
const person = new Person();
menjalankan constructor.
Sedangkan @Logger sudah diproses ketika class definition dievaluasi.
20. Contoh timeline lengkap
Mari kita buat contoh yang lebih lengkap:
@ClassLogger
class Person {
@PropertyLogger
name: string;
@MethodLogger
calculateAge(
@ParameterLogger dateOfBirth: string
) {
console.log("calculateAge executed");
}
constructor(name: string) {
console.log("constructor executed");
this.name = name;
}
}
Ada:
Class decorator
Property decorator
Method decorator
Parameter decorator
Constructor
Method
Penting:
Decorator bukan sesuatu yang menunggu instance.
Ketika class diproses, decorator akan diproses sesuai aturan execution order-nya.
Kemudian baru ketika kita melakukan:
const person = new Person("Budi");
constructor berjalan.
Dan ketika:
person.calculateAge("2000-01-01");
method berjalan.
21. Cara berpikir yang paling aman
Kalau kamu melihat decorator, tanyakan dua pertanyaan:
Pertanyaan 1
Decorator ini ditempel di mana?
class?
property?
method?
parameter?
Pertanyaan 2
Apa execution order untuk tempat tersebut?
class
→ bottom to top
property
→ top to bottom
method
→ top to bottom
parameter
→ left to right
Dengan dua pertanyaan ini kamu bisa menentukan urutannya.
22. Contoh latihan mental
Misalnya:
@A
@B
@C
class Person {}
Tanya:
Ini decorator pada apa?
Jawab:
Class
Aturannya:
Bottom → Top
Maka:
C → B → A
Contoh kedua:
class Person {
@A
@B
@C
name: string;
}
Ini property.
Aturannya:
Top → Bottom
Maka:
A → B → C
Contoh ketiga:
class Person {
@A
@B
@C
calculateAge() {}
}
Ini method.
Maka:
A → B → C
Contoh keempat:
calculateAge(
@A @B @C dateOfBirth: string
) {}
Ini parameter.
Maka:
A → B → C
23. Kenapa lecture ini penting?
Karena decorator biasanya digunakan untuk menambahkan behavior seperti:
- logging
- validation
- authorization
- caching
- metadata
- dependency injection
- routing
- monitoring
Misalnya kita punya:
@Logger
calculateAge() {}
Decorator bisa digunakan untuk menambahkan:
sebelum method
↓
logging
↓
method asli
↓
logging
↓
selesai
Kalau ada banyak decorator, urutannya akan memengaruhi hasil.
Contohnya:
@Authentication
@Logger
calculateAge() {}
berbeda dengan:
@Logger
@Authentication
calculateAge() {}
Karena decorator memiliki urutan pemrosesan.
24. Hubungan dengan descriptor
Kita juga bisa menghubungkan lecture ini dengan lecture sebelumnya.
Method decorator:
function Logger(
target: any,
methodName: string,
descriptor: PropertyDescriptor
) {
}
Decorator diproses ketika class definition dievaluasi.
Kemudian decorator bisa menggunakan:
descriptor.value
untuk mendapatkan function method.
Secara konsep:
class definition
↓
method decorator
↓
descriptor
↓
descriptor.value
↓
method function
Jadi lecture ini sebenarnya sedang membangun fondasi untuk lecture berikutnya ketika kita mulai memodifikasi behavior method menggunakan decorator.
25. Kesalahan pemahaman yang sering terjadi
❌ Salah
“Decorator dijalankan ketika saya membuat object.”
const person = new Person();
✅ Benar
Decorator diproses ketika class definition dievaluasi, sebelum kita perlu membuat instance.
❌ Salah
“Decorator pada method dijalankan setiap kali method dipanggil.”
Misalnya:
person.calculateAge();
person.calculateAge();
person.calculateAge();
Bukan berarti decorator dijalankan 3 kali.
Decorator bukan event listener otomatis yang dipanggil setiap method invocation.
❌ Salah
“Semua decorator selalu bottom-to-top.”
Tidak.
Untuk pola legacy yang dibahas lecture:
Class → bottom → top
Property → top → bottom
Method → top → bottom
Parameter → left → right
26. Satu catatan penting tentang versi TypeScript
Karena lecture ini menggunakan legacy/experimental decorators, execution-order dan API yang diajarkan adalah konteks decorator lama yang umum digunakan dalam course-course TypeScript/Angular/NestJS lama.
TypeScript modern juga memiliki standard decorators yang model API dan beberapa detail semantiknya berbeda.
Jadi kalau nanti kamu membaca dokumentasi TypeScript modern dan menemukan aturan yang terlihat berbeda, jangan bingung. Untuk mengikuti lecture ini, pahami dulu model decorator yang sedang digunakan oleh course.
27. Cheat sheet
Kalau mau dibuat super ringkas:
╔══════════════════════════════════════╗
║ DECORATOR EXECUTION ║
╠══════════════════════════════════════╣
║ Class → Bottom → Top ║
║ Property → Top → Bottom ║
║ Method → Top → Bottom ║
║ Parameter → Left → Right ║
╚══════════════════════════════════════╝
Dan aturan waktunya:
CLASS DEFINITION
↓
DECORATORS DIPROSES
↓
CLASS SELESAI DIDEFINISIKAN
↓
new Person()
↓
CONSTRUCTOR
↓
person.calculateAge()
↓
METHOD
28. Inti lecture dalam satu kalimat
Kalau saya sederhanakan seluruh lecture menjadi satu kalimat:
Decorator diproses saat definisi class dievaluasi, bukan saat instance atau method dipanggil, dan urutan pemrosesannya bergantung pada tempat decorator dipasang.
Yang paling wajib kamu hafal:
Class → BOTTOM → TOP
Property → TOP → BOTTOM
Method → TOP → BOTTOM
Parameter → LEFT → RIGHT
Dan satu lagi yang sangat penting:
Decorator execution ≠ method execution ≠ constructor execution.
Itu tiga kejadian yang berbeda.