Pertama, ingatlah bahwa JavaScript pada dasarnya adalah bahasa prototipe , bukan bahasa berbasis kelas 1 . Foobukan kelas, ini adalah fungsi, yang merupakan objek. Anda dapat instantiate objek dari fungsi itu menggunakan newkata kunci yang akan memungkinkan Anda untuk membuat sesuatu yang mirip dengan kelas dalam bahasa OOP standar.
Saya sarankan untuk mengabaikan __proto__sebagian besar waktu karena memiliki dukungan browser lintas yang buruk, dan alih-alih fokus pada belajar tentang caranyaprototype kerjanya.
Jika Anda memiliki instance objek yang dibuat dari fungsi 2 dan Anda mengakses salah satu anggotanya (metode, atribut, properti, konstanta dll) dengan cara apa pun, akses akan mengalir ke hierarki prototipe sampai salah satu (a) menemukan anggota, atau (b) tidak menemukan prototipe lain.
Hirarki dimulai pada objek yang dipanggil, dan kemudian mencari objek prototipe. Jika objek prototipe memiliki prototipe, itu akan berulang, jika tidak ada prototipe, undefineddikembalikan.
Sebagai contoh:
foo = {bar: 'baz'};
console.log(foo.bar); // logs "baz"
foo = {};
console.log(foo.bar); // logs undefined
function Foo(){}
Foo.prototype = {bar: 'baz'};
f = new Foo();
console.log(f.bar);
// logs "baz" because the object f doesn't have an attribute "bar"
// so it checks the prototype
f.bar = 'buzz';
console.log( f.bar ); // logs "buzz" because f has an attribute "bar" set
Bagi saya sepertinya Anda setidaknya sudah memahami bagian-bagian "dasar" ini, tetapi saya perlu membuatnya eksplisit hanya untuk memastikan.
Dalam JavaScript, semuanya adalah objek 3 .
segala sesuatu adalah objek.
function Foo(){} tidak hanya mendefinisikan fungsi baru, ia mendefinisikan objek fungsi baru yang dapat diakses menggunakan Foo .
Inilah sebabnya mengapa Anda dapat mengakses Fooprototipe dengan Foo.prototype.
Yang juga dapat Anda lakukan adalah mengatur lebih banyak fungsi pada Foo:
Foo.talk = function () {
alert('hello world!');
};
Fungsi baru ini dapat diakses menggunakan:
Foo.talk();
Saya harap sekarang Anda memperhatikan kesamaan antara fungsi pada objek fungsi dan metode statis.
Anggap f = new Foo();sebagai membuat instance kelas, Foo.prototype.bar = function(){...}sebagai mendefinisikan metode bersama untuk kelas, dan Foo.baz = function(){...}sebagai mendefinisikan metode statis publik untuk kelas.
ECMAScript 2015 memperkenalkan beragam gula sintaksis untuk deklarasi semacam ini agar lebih mudah diimplementasikan sementara juga lebih mudah dibaca. Oleh karena itu, contoh sebelumnya dapat ditulis sebagai:
class Foo {
bar() {...}
static baz() {...}
}
yang memungkinkan bardisebut sebagai:
const f = new Foo()
f.bar()
dan bazdisebut sebagai:
Foo.baz()
1: classadalah "Future Reserved Word" dalam spesifikasi ECMAScript 5 , tetapi ES6 memperkenalkan kemampuan untuk mendefinisikan kelas menggunakan classkata kunci.
2: pada dasarnya instance kelas yang dibuat oleh konstruktor, tetapi ada banyak perbedaan nuansa yang saya tidak ingin menyesatkan Anda
3: nilai-nilai primitif — yang meliputi undefined,, nullboolean, angka, dan string — bukan objek teknis karena mereka adalah implementasi bahasa tingkat rendah. Boolean, angka, dan string masih berinteraksi dengan rantai prototipe seolah-olah mereka objek, jadi untuk keperluan jawaban ini, lebih mudah untuk menganggap mereka "objek" meskipun mereka tidak cukup.
Foo.talk = function ...