Kata new
kunci dalam JavaScript bisa sangat membingungkan ketika pertama kali ditemukan, karena orang cenderung berpikir bahwa JavaScript bukan bahasa pemrograman berorientasi objek.
- Apa itu?
- Masalah apa yang dipecahkan?
- Kapan itu tepat dan kapan tidak?
javascript
new-operator
Alon Gubkin
sumber
sumber
Jawaban:
Itu melakukan 5 hal:
this
titik variabel ke objek yang baru dibuat.this
disebutkan.null
referensi non- objek. Dalam hal ini, referensi objek itu dikembalikan sebagai gantinya.Catatan: fungsi konstruktor merujuk ke fungsi setelah
new
kata kunci, seperti padaSetelah ini selesai, jika properti yang tidak ditentukan dari objek baru diminta, skrip akan memeriksa objek [[prototipe]] objek untuk properti sebagai gantinya. Ini adalah bagaimana Anda bisa mendapatkan sesuatu yang mirip dengan warisan kelas tradisional di JavaScript.
Bagian yang paling sulit tentang ini adalah titik nomor 2. Setiap objek (termasuk fungsi) memiliki properti internal ini disebut [[prototipe]] . Ini hanya dapat diatur pada waktu pembuatan objek, baik dengan yang baru , dengan Object.create , atau berdasarkan literal (fungsi default ke Function.prototype, angka ke Number.prototype, dll.). Itu hanya dapat dibaca dengan Object.getPrototypeOf (someObject) . Tidak ada cara lain untuk mengatur atau membaca nilai ini.
Fungsi, selain properti [[prototipe]] tersembunyi , juga memiliki properti yang disebut prototipe , dan inilah yang dapat Anda akses, dan modifikasi, untuk menyediakan properti dan metode yang diwarisi untuk objek yang Anda buat.
Berikut ini sebuah contoh:
Ini seperti warisan kelas karena sekarang, benda apa pun yang Anda buat menggunakan
new ObjMaker()
juga akan tampak mewarisi properti 'b'.Jika Anda menginginkan sesuatu seperti subclass, maka Anda melakukan ini:
Saya membaca satu ton sampah tentang hal ini sebelum akhirnya menemukan halaman ini , di mana ini dijelaskan dengan sangat baik dengan diagram yang bagus.
sumber
ObjMaker
didefinisikan sebagai fungsi yang mengembalikan nilai?new
ada sehingga Anda tidak perlu menulis metode pabrik untuk membangun / menyalin fungsi / objek. Ini berarti, "Salin ini, membuatnya seperti 'kelas' induknya; lakukan secara efisien dan benar; dan simpan info warisan yang hanya dapat diakses oleh saya, JS, secara internal". Untuk melakukannya, ia memodifikasi bagianprototype
dalam objek baru yang tidak dapat diakses yang tidak dapat diakses untuk mengenkapsulasi anggota yang diwariskan, meniru rantai pewarisan OO klasik (yang tidak dapat dimodifikasi runtime). Anda dapat mensimulasikan ini tanpanew
, tetapi warisan akan dapat dimodifikasi runtime. Baik? Buruk? Terserah kamu.Notice that this pattern is deprecated!
. Apa pola up-to-date yang benar untuk mengatur prototipe kelas?Misalkan Anda memiliki fungsi ini:
Jika Anda menyebut ini sebagai fungsi mandiri seperti:
Menjalankan fungsi ini akan menambahkan dua properti ke
window
objek (A
danB
). Itu menambahkannya kewindow
karenawindow
adalah objek yang disebut fungsi ketika Anda mengeksekusi seperti itu, danthis
dalam suatu fungsi adalah objek yang disebut fungsi. Setidaknya dalam Javascript.Sekarang, sebut saja seperti ini dengan
new
:Apa yang terjadi ketika Anda menambahkan
new
panggilan fungsi adalah bahwa objek baru dibuat (hanyavar bar = new Object()
) dan bahwa dithis
dalam fungsi menunjuk ke yang baruObject
Anda buat, bukan ke objek yang disebut fungsi. Jadibar
sekarang menjadi objek dengan propertiA
danB
. Fungsi apa pun bisa menjadi konstruktor, tidak selalu masuk akal.sumber
window
tersirat. Bahkan dalam penutupan, bahkan jika anonim. Namun, dalam contoh ini adalah doa metode sederhana di jendela:Foo();
=>[default context].Foo();
=>window.Foo();
. Dalam ungkapan iniwindow
adalah konteks (bukan hanya penelepon , yang tidak masalah).Selain jawaban Daniel Howard, berikut adalah apa yang
new
dilakukan (atau setidaknya tampaknya dilakukan):Sementara
setara dengan
sumber
func.prototype
menjadinull
? Bisakah Anda menjelaskan sedikit tentang itu?A.prototype = null;
Dalam kasus itunew A()
akan menghasilkan objek, itulah prototipe internal menunjuk keObject
objek: jsfiddle.net/Mk42ZObject(ret) === ret
.typeof
tes hanya membuatnya lebih mudah untuk memahami apa yang terjadi di balik layar.Bagi pemula untuk memahaminya dengan lebih baik
coba kode berikut di konsol browser.
Sekarang Anda dapat membaca jawaban komunitas wiki :)
sumber
return this;
menghasilkan output yang sama.Ini digunakan tepat untuk itu. Anda mendefinisikan konstruktor fungsi seperti:
Namun manfaat tambahan yang dimiliki ECMAScript adalah Anda dapat memperluas dengan
.prototype
properti, sehingga kami dapat melakukan sesuatu seperti ...Semua objek yang dibuat dari konstruktor ini sekarang akan memiliki
getName
karena rantai prototipe yang mereka akses.sumber
class
kata kunci tetapi Anda dapat melakukan hal yang sama.JavaScript adalah bahasa pemrograman berorientasi objek dan digunakan tepat untuk membuat instance. Ini berbasis prototipe, bukan berbasis kelas, tetapi itu tidak berarti bahwa itu tidak berorientasi objek.
sumber
Javascript adalah bahasa pemrograman dinamis yang mendukung paradigma pemrograman berorientasi objek, dan digunakan untuk membuat instance objek baru.
Kelas tidak diperlukan untuk objek - Javascript adalah bahasa berbasis prototipe .
sumber
Sudah ada beberapa jawaban yang sangat bagus tetapi saya memposting yang baru untuk menekankan pengamatan saya pada kasus III di bawah ini tentang apa yang terjadi ketika Anda memiliki pernyataan pengembalian eksplisit dalam fungsi yang sedang Anda
new
lakukan. Lihat kasus-kasus di bawah ini:Kasus I :
Di atas adalah kasus sederhana memanggil fungsi anonim yang ditunjuk oleh
Foo
. Ketika Anda memanggil fungsi ini, ia kembaliundefined
. Karena tidak ada pernyataan pengembalian yang eksplisit maka penerjemah JavaScript dengan paksa memasukkanreturn undefined;
pernyataan di akhir fungsi. Di sini jendela adalah objek doa (kontekstualthis
) yang mendapat properti baruA
danB
.Kasus II :
Di sini, penerjemah JavaScript yang melihat
new
kata kunci membuat objek baru yang bertindak sebagai objek doa (kontekstualthis
) dari fungsi anonim yang ditunjukkan olehFoo
. Dalam hal iniA
danB
menjadi properti pada objek yang baru dibuat (sebagai pengganti objek jendela). Karena Anda tidak memiliki pernyataan pengembalian yang eksplisit, maka penerjemah JavaScript dengan paksa memasukkan pernyataan kembali untuk mengembalikan objek baru yang dibuat karena penggunaannew
kata kunci.Kasus III :
Di sini, lagi, penerjemah JavaScript yang melihat
new
kata kunci membuat objek baru yang bertindak sebagai objek doa (kontekstualthis
) dari fungsi anonim yang ditunjukkan olehFoo
. Sekali lagi,A
danB
menjadi properti pada objek yang baru dibuat. Tetapi kali ini Anda memiliki pernyataan pengembalian yang eksplisit sehingga penerjemah JavaScript tidak akan melakukan apa pun sendiri.Hal yang perlu diperhatikan dalam kasus III adalah bahwa objek yang dibuat karena
new
kata kunci hilang dari radar Anda.bar
sebenarnya menunjuk ke objek yang sama sekali berbeda yang bukan yang dibuat penerjemah JavaScript karenanew
kata kunci.Mengutip David Flanagan dari JavaScripit: The Definitive Guide (Edisi ke-6), Ch. 4, Halaman # 62:
--- Info Tambahan ---
Fungsi yang digunakan dalam cuplikan kode dari kasus di atas memiliki nama khusus di dunia JS seperti di bawah ini:
Kasus I dan II - Fungsi konstruktor
Kasus III - Fungsi pabrik. Fungsi pabrik tidak boleh digunakan dengan
new
kata kunci yang telah saya lakukan untuk menjelaskan konsep di utas saat ini.Anda dapat membaca tentang perbedaan di antara mereka di utas ini .
sumber
terkadang kode lebih mudah daripada kata-kata:
bagi saya, selama saya tidak membuat prototipe, saya menggunakan gaya func2 karena memberi saya sedikit lebih banyak fleksibilitas di dalam dan di luar fungsi.
sumber
B1 = new func2(2);
<- Kenapa ini tidak adaB1.y
?Kata
new
kunci mengubah konteks di mana fungsi sedang dijalankan dan mengembalikan pointer ke konteks itu.Ketika Anda tidak menggunakan
new
kata kunci, konteks di mana fungsiVehicle()
berjalan adalah konteks yang sama dari mana Anda memanggilVehicle
fungsi. Katathis
kunci akan merujuk pada konteks yang sama. Saat Anda menggunakannew Vehicle()
, konteks baru dibuat sehingga kata kuncithis
di dalam fungsi merujuk ke konteks baru. Apa yang Anda dapatkan sebagai balasan adalah konteks yang baru dibuat.sumber
Kata
new
kunci untuk membuat instance objek baru. Dan ya, javascript adalah bahasa pemrograman dinamis, yang mendukung paradigma pemrograman berorientasi objek. Konvensi tentang penamaan objek adalah, selalu gunakan huruf kapital untuk objek yang seharusnya dipakai oleh kata kunci baru.sumber
Ringkasan:
Kata
new
kunci digunakan dalam javascript untuk membuat objek dari fungsi konstruktor. Katanew
kunci harus ditempatkan sebelum panggilan fungsi konstruktor dan akan melakukan hal-hal berikut:this
kata kunci ke objek yang baru dibuat dan menjalankan fungsi konstruktorContoh:
Apa yang sebenarnya terjadi:
const doggie
mengatakan: Kita membutuhkan memori untuk mendeklarasikan variabel.=
mengatakan: Kami akan menginisialisasi variabel ini dengan ekspresi setelah=
new Dog(12)
. Mesin JS melihat kata kunci baru, membuat objek baru dan menetapkan prototipe ke Dog.prototypethis
nilai yang ditetapkan ke objek baru. Pada langkah ini adalah tempat usia ditetapkan untuk objek doggie yang baru dibuat.sumber
Kata
new
kunci membuat instance objek yang menggunakan fungsi sebagai konstruktor. Contohnya:Contoh mewarisi dari
prototype
fungsi konstruktor. Jadi diberikan contoh di atas ...sumber
Yah JavaScript per si bisa sangat berbeda dari platform ke platform karena selalu merupakan implementasi dari spesifikasi asli EcmaScript.
Bagaimanapun, terlepas dari implementasi, semua implementasi JavaScript yang mengikuti spesifikasi EcmaScript benar, akan memberi Anda Bahasa Berorientasi Objek. Menurut standar ES:
Jadi sekarang kita telah sepakat bahwa JavaScript adalah implementasi dari EcmaScript dan oleh karena itu bahasa berorientasi objek. Definisi
new
operasi dalam bahasa berorientasi objek apa pun, mengatakan bahwa kata kunci tersebut digunakan untuk membuat turunan objek dari kelas jenis tertentu (termasuk jenis anonim, dalam kasus seperti C #).Di EcmaScript kami tidak menggunakan kelas, karena Anda dapat membaca dari spesifikasi:
sumber