Pertama, ingatlah bahwa JavaScript pada dasarnya adalah bahasa prototipe , bukan bahasa berbasis kelas 1 . Foo
bukan kelas, ini adalah fungsi, yang merupakan objek. Anda dapat instantiate objek dari fungsi itu menggunakan new
kata 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, undefined
dikembalikan.
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 Foo
prototipe 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 bar
disebut sebagai:
const f = new Foo()
f.bar()
dan baz
disebut sebagai:
Foo.baz()
1: class
adalah "Future Reserved Word" dalam spesifikasi ECMAScript 5 , tetapi ES6 memperkenalkan kemampuan untuk mendefinisikan kelas menggunakan class
kata 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
,, null
boolean, 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 ...