Perkenalan
1. Jenis referensi
Tipe referensi adalah tipe internal dalam JavaScript. Hal ini terutama digunakan sebagai referensi, menggantikan variabel atau fungsi. Tentu saja, ketika nilai sebenarnya dibutuhkan, nilai sebenarnya dapat ditemukan melaluinya.
2. Struktur tipe referensi
Nilai dari tipe referensi terdiri dari dua bagian. Satu adalah objek yang dirujuk oleh nilai tipe referensi tersebut. Di sini kita menyebutnya basis, dan yang lainnya adalah nama objek dari objek yang dirujuk dalam basis . Diwakili dalam kode semu:
Copy kode kodenya sebagai berikut:
var valueOfReferenceType = {
dasar: <objek dasar>,
Nama Properti: <nama properti>
};
3. Skenario penggunaan
Ada dua skenario penggunaan untuk tipe referensi:
(1) Saat memproses pengenal
Pengidentifikasi adalah nama variabel, nama fungsi, nama parameter fungsi, dan nama properti yang tidak dikenal dalam objek global.
(2) Saat memproses pengakses properti
Copy kode kodenya sebagai berikut:
var foo = 10;
bilah fungsi(){}
Dalam hasil antara operasi, jenis referensi sesuai dengan
Copy kode kodenya sebagai berikut:
var fooReferensi = {
dasar: global,
Nama Properti: 'foo'
};
var barReferensi = {
dasar: global,
Nama Properti: 'bilah'
};
Masih perlu dijelaskan dasar-dasarnya di sini. Dalam JavaScript, semua objek atau fungsi memiliki objeknya sendiri. Siapa pun yang telah membaca artikel saya sebelumnya tahu bahwa ada objek variabel di setiap konteks eksekusi untuk mengelola variabel atau fungsi dalam konteks eksekusi ini .
Jadi, ketika berhadapan dengan pengidentifikasi:
Dalam konteks global, sudah jelas bahwa base === globalVO === global
Dalam konteks eksekusi fungsi, base === VO/AO
Namun properti objek pemrosesan adalah:
Ini bahkan lebih sederhana, base === owerObject
4. Dapatkan nilai sebenarnya dari tipe referensi
Seperti yang kami katakan di awal, tipe referensi hanyalah referensi, namun tidak menyimpan nilai sebenarnya. Ketika nilai riil dibutuhkan, maka dapat diperoleh melalui serangkaian algoritma internal. Kita dapat menggambarkan algoritma ini dengan pseudocode sederhana:
Copy kode kodenya sebagai berikut:
fungsi GetValue(nilai) {
if (Jenis(nilai) != Referensi) {
nilai kembalian;
}
var base = GetBase(nilai);
jika (basis === nol) {
membuang ReferensiError baru;
}
basis pengembalian.[[Dapatkan]](GetPropertyName(nilai));
}
Metode internal [[Dapatkan]] mengembalikan nilai sebenarnya dari properti objek, termasuk analisis properti yang diwariskan dalam rantai prototipe. Jadi melalui GetValue kita juga bisa dengan mudah mendapatkan nilai sebenarnya dari tipe referensi. Misalnya:
Copy kode kodenya sebagai berikut:
DapatkanNilai(fooReference); // 10
GetValue(barReference); // objek fungsi "bar"
Jadi kapan kita perlu mendapatkan nilai sebenarnya dari tipe referensi?
Umumnya, ketika tipe referensi perlu ditetapkan, berpartisipasi dalam operasi, atau dipanggil, nilai sebenarnya perlu diperoleh melalui metode GetValue. (Catatan: Objek yang diperoleh melalui GetValue bukan lagi tipe referensi)
Hubungan antara tipe referensi dan ini
Tipe referensi terutama berkaitan erat dengan titik this dalam konteks fungsi, dan terlihat sangat berbeda pada waktu yang berbeda, jadi kami memperkenalkan tipe referensi untuk secara spesifik menjelaskan kinerja this dalam konteks fungsi.
Aturan umum untuk menentukan nilai this dalam konteks fungsi adalah sebagai berikut:
Dalam konteks suatu fungsi, ini disediakan oleh pemanggil dan ditentukan oleh cara pemanggilan fungsi tersebut. Jika sisi kiri braket pemanggil () adalah nilai tipe referensi, ini akan disetel ke objek dasar dari nilai tipe referensi. Dalam kasus lain (properti lain yang berbeda dari tipe referensi), nilai ini akan menjadi nol . Namun, tidak ada situasi aktual di mana nilai this adalah null, karena ketika nilai this adalah null, nilainya secara implisit akan dikonversi ke objek global. Catatan: Dalam ECMAScript edisi kelima, konversi ke variabel global tidak lagi dipaksakan, tetapi ditetapkan ke tidak terdefinisi.
Di bawah ini kita akan membahas tiga situasi berdasarkan perbedaan di sisi kiri braket pemanggil:
(1) Sisi kiri braket pemanggil adalah nilai tipe referensi
Ini tidak memerlukan terlalu banyak analisis. Objek dasarnya adalah nilainya. Jika dideklarasikan dalam variabel global, maka ia menunjuk ke objek global.
Copy kode kodenya sebagai berikut:
var objek saya = {
foo : fungsi(){
konsol.log(ini);
}
}
myObject.foo(); //Tidak ada keraguan bahwa basis dari foo adalah myObject, jadi this dalam metode foo menunjuk ke myObject.
(2) Sisi kiri braket pemanggil adalah nilai tipe referensi, namun nilai ini nol
Copy kode kodenya sebagai berikut:
fungsi fungsi saya() {
var foo = fungsi(){
konsol.log(ini);
}
foo(); //AO.foo() => null.foo()
}
myFunction(); //Keluaran: Jendela {atas: Jendela, jendela: Jendela...}
Ketika fungsi internal dipanggil, basis dari fungsi internal harus berupa objek aktif (OA) dalam konteks eksekusi saat ini. Namun, dalam JavaScript, ketika OA digunakan sebagai basis, itu diperlakukan sebagai nol izinkan ini menjadi null, semua basis disetel ke objek global (ini adalah sumber kesalahan desain pada pola pemanggilan fungsi ini sebelumnya). Jadi dalam hal ini, ini menunjuk pada objek global.
(3) Memanggil nilai di sisi kiri tanda kurung yang bukan merupakan tipe referensi
Copy kode kodenya sebagai berikut:
//Contoh sederhana
(fungsi () {
konsol.log(ini); // null => global
})();
//Contoh yang lebih kompleks
var foo = {
bilah: fungsi () {
konsol.log(ini);
}
};
foo.bar(); // Referensi, OK => foo
(foo.bar)(); // Referensi, OK => foo
(foo.bar = foo.bar)(); // global
(salah || foo.bar)(); // global
(foo.bar, foo.bar)(); // global
Ketika sisi kiri braket pemanggil bukan tipe referensi tetapi tipe lain, ini secara otomatis disetel ke null dan hasilnya adalah objek global.
Pada contoh pertama, fungsi langsung memiliki ekspresi di sisi kiri tanda kurung pemanggilan fungsi, bukan referensi.
Contoh kedua jauh lebih rumit, mari kita analisa satu per satu:
foo.bar(), tidak ada keraguan tentang ini, base adalah foo, dan ini menunjuk ke foo.
(foo.bar)(), tanda kurung digunakan di sini, yang bertindak sebagai simbol pengelompokan, yaitu tidak memaksa tipe referensi untuk mengeksekusi metode GetValue, dan hasil eksekusi sama persis seperti di atas.
Tiga berikutnya, di dalam tanda kurung, adalah operasi penugasan, atau operasi dan operasi koma. Semuanya memaksa tipe referensi untuk mengeksekusi metode GetValue, sehingga mengembalikan objek fungsi. Dengan cara ini, sisi kiri tanda kurung pemanggilan fungsi tidak lagi menjadi tipe referensi, jadi ini menunjuk ke objek global.
Meringkaskan
Mengenai tipe referensi, sebenarnya saya belum tahu banyak tentang ini. Saya baru melihat bab ini di blog Paman Tom. Untuk menjelaskan prinsip nilai ini dalam mode pemanggilan fungsi, saya membuat analisis khusus luar biasa. Saya Saya selalu berpikir bahwa harus ada hubungan antara tipe referensi dan referensi berdasarkan nilai. Kalau sebelumnya ada hubungan antara keduanya, dan kalau memang ada hubungannya, hubungan seperti apa, saya masih perlu terus belajar dan meneliti.
Saya harap Anda dapat berkomunikasi lebih banyak. Saya ingin berterima kasih kepada Paman Tom untuk ini.