Sebuah Survei JavaScript Bahasa Pemrograman

Douglas Crockford 
www.crockford.com

© 2002 Douglas Crockford

Ikhtisar

Dokumen ini merupakan pengantar ke JavaScript Programming Language untuk programmer profesional. Ini adalah bahasa kecil, jadi jika Anda sudah familiar dengan bahasa lain, maka ini tidak akan terlalu menuntut.

JavaScript tidak Java. Mereka adalah dua bahasa yang sangat berbeda. JavaScript tidak subset dari Jawa. Hal ini tidak ditafsirkan Java. (Jawa ditafsirkan Java!) Sintaks JavaScript saham C-keluarga dengan Java, tetapi pada tingkat yang lebih dalam itu menunjukkan kesamaan yang lebih besar ke bahasa Skema dan Diri . Ini adalah bahasa kecil, tetapi juga language.You mengejutkan kuat dan ekspresif harus melihat itu. Anda akan menemukan bahwa itu adalah bukan bahasa mainan, tapi bahasa pemrograman penuh dengan banyak sifat khas.

JavaScript adalah bahasa biasa yang tidak akan mengambil banyak waktu untuk belajar. Hal ini lebih cocok untuk beberapa tugas, seperti pemrograman client, dari Jawa.Dalam praktek saya sendiri, saya telah menemukan bahwa bekerja dengan JavaScript telah membuat saya programmer Java lebih baik karena memperkenalkan saya untuk satu set yang berguna teknik dinamis.

Ketika JavaScript pertama kali diperkenalkan, saya menganggapnya sebagai tidak layak perhatian saya. Banyak kemudian, saya mengambil lain melihat hal itu dan menemukan bahwa tersembunyi di browser adalah bahasa pemrograman yang sangat baik. sikap awal saya didasarkan pada posisi awal JavaScript oleh Sun dan Netscape.Mereka membuat banyak salah saji sekitar JavaScript untuk menghindari posisi JavaScript sebagai pesaing Java. Mereka salah saji terus bergema di sejumlah buku JavaScript ditulis buruk yang ditujukan untuk dummies dan amatir pasar.

 

Sejarah

JavaScript dikembangkan oleh Brendan Eich di Netscape sebagai di halaman bahasa scripting untuk Navigator 2 . Ini adalah bahasa pemrograman yang sangat ekspresif dinamis. Karena linkage untuk web browser, langsung menjadi populer besar-besaran. Ini tidak pernah mendapat masa percobaan di mana itu bisa diperbaiki dan dipoles didasarkan pada penggunaan aktual. Bahasa ini kuat dan cacat.

Dokumen ini menjelaskan ECMAScript Edition 3 (alias JavaScript 1.5). Microsoft dan Netscape sedang mengembangkan revisi statis yang tidak memperbaiki kekurangan bahasa ini. Bahwa bahasa baru tidak JavaScript dan berada di luar lingkup dokumen ini.

Jenis Data

JavaScript berisi kumpulan kecil dari jenis data. Ini memiliki tiga jenis primitif boolean , jumlah , dan tali dan nilai-nilai khusus nol dan terdefinisi . Segala sesuatu yang lain adalah variasi pada objek jenis.

Boolean memiliki dua nilai: benar dan salah .

Jumlah ini 64-bit floating point, mirip dengan Jawa ganda dan ganda . Tidak ada tipe integer. Pembagian antara dua bilangan bulat dapat menghasilkan hasil pecahan. Jumlah ini juga termasuk nilai-nilai khusus NaN (bukan angka) dan Infinity .

String adalah urutan nol atau lebih karakter Unicode. Tidak ada jenis karakter yang terpisah. Sebuah karakter diwakili sebagai string panjang 1. string Literal dikutip menggunakan atau " karakter. Karakter kutipan dapat digunakan secara bergantian, tetapi mereka harus cocok.

"Ini adalah string. '

"Bukankah ini sebuah string? Ya!"

'A' // Karakter A

"" // Sebuah string kosong

Pelarian dilakukan dengan \ karakter, seperti di Jawa. String yang berubah. String memiliki panjang anggota yang digunakan untuk menentukan jumlah karakter dalam string.

var s = "Hello World!";
s.length == 12

Hal ini dimungkinkan untuk menambahkan metode untuk tipe sederhana. Jadi, misalnya, Anda dapat menambahkan int () metode untuk semua nomor, sehinggaMath.PI.int () menghasilkan 3 .

Penerapan dapat memberikan jenis lain, seperti Tanggal dan Regular Expressions, tetapi ini benar-benar hanya objek. Segala sesuatu yang lain hanya objek.

benda

JavaScript memiliki kemudahan notasi yang sangat bagus untuk memanipulasi hashtables.

adalah myHashtable = {};

Pernyataan ini membuat hashtable baru dan memberikan ke variabel lokal baru. JavaScript longgar diketik, jadi kita tidak menggunakan nama ketik deklarasi. Kami menggunakan notasi subscript untuk menambah, mengganti, atau mengambil elemen dalam hashtable.

myHashtable [ "nama"] = "Carl Hollywood,";

Ada juga notasi dot yang sedikit lebih nyaman.

myHashtable.city = "Anytown";

Dot notasi dapat digunakan ketika subscript adalah konstan string dalam bentuk pengenal hukum. Karena kesalahan dalam definisi bahasa, kata-kata dicadangkan tidak dapat digunakan dalam notasi dot, tetapi mereka dapat digunakan dalam notasi subscript.

Anda dapat melihat bahwa notasi hashtable JavaScript ini sangat mirip dengan Jawa objek dan array yang notasi. JavaScript mengambil ini lebih jauh: objek dan hashtables adalah hal yang sama, jadi saya bisa menulis

var myHashtable = new Object ();

dan hasilnya akan persis sama.

Ada kemampuan pencacahan dibangun ke dalam untuk pernyataan.

for (var n di myHashtable) {
    if (myHashtable.hasOwnProperty (n)) {
        document.writeln ( "<p>" + n + ":" + myHashtable [n] + "</ p>");
    }
}

Hasilnya akan

<p> Nama: Carl Hollywood, </ p>
<p> kota: Anytown </ p>

Sebuah objek adalah wadah referenceable dari pasangan nama / nilai. Nama-nama string (atau unsur-unsur lain seperti nomor yang dikonversi ke string). Nilai dapat berupa jenis data, termasuk benda-benda lainnya. Benda biasanya diimplementasikan sebagai hash-meja, tapi tidak ada sifat hash-table (seperti fungsi hash atau metode mengulangi) terlihat.

Objek dapat dengan mudah bersarang di dalam benda-benda lain, dan ekspresi dapat mencapai ke dalam objek batin.

this.div = document.body.children [document.body.children.length - 1];

Dalam objek notasi literal, deskripsi objek adalah seperangkat pasangan nama / nilai dipisahkan koma di dalam kurung kurawal. Nama-nama bisa pengidentifikasi atau string diikuti dengan titik dua. Karena kesalahan dalam definisi bahasa, kata-kata dicadangkan tidak dapat digunakan dalam bentuk pengenal, tetapi mereka dapat digunakan dalam bentuk string. Nilai-nilai bisa literal atau ekspresi dari jenis apa pun.

var myObject = {name: "Jack B. Lincah", 'goto': 'Penjara', kelas: 'A', tingkat: 3};

pulang {
    acara: acara,
    op: event.type,
    ke: event.srcElement,
    x: event.clientX + document.body.scrollLeft,
    y: event.clientY + document.body.scrollTop};

emptyObject = {};

Literal objek JavaScript adalah dasar dari JSON format data interchange.

anggota baru dapat ditambahkan ke objek apapun setiap saat dengan tugas.

myObject.nickname = 'Jackie Bee';

Array dan fungsi diimplementasikan sebagai objek.

array

Array dalam JavaScript juga objek hashtable. Hal ini membuat mereka sangat cocok untuk aplikasi array tipis. Ketika Anda membangun sebuah array, Anda tidak perlu untuk menyatakan ukuran. Array tumbuh secara otomatis, seperti vektor Jawa. Nilai-nilai yang terletak kunci, bukan oleh offset. Hal ini membuat array JavaScript sangat nyaman untuk digunakan, tetapi tidak cocok untuk aplikasi dalam analisis numerik.

Perbedaan utama antara objek dan array adalah panjang properti. The panjang properti selalu 1 lebih besar dari tombol bulat terbesar dalam array. Ada dua cara untuk membuat array baru:

var myArray = [];
var myArray = new Array ();

Array tidak diketik. Mereka dapat berisi angka, string, boolean, benda, fungsi, dan arrays.You dapat mencampur string dan angka dan objek dalam array yang sama. Anda dapat menggunakan array sebagai urutan bersarang umum, sebanyak s-ekspresi. Indeks pertama dalam array biasanya nol.

Ketika item baru ditambahkan ke array dan subscript adalah integer yang lebih besar dari nilai saat ini dari panjang , maka panjang diubah ke subscript ditambah satu. Ini adalah fitur kenyamanan yang membuatnya mudah untuk menggunakan untuk loop untuk pergi melalui elemen array.

Array memiliki notasi literal, serupa dengan objek.

myList = [ 'oat', 'kacang polong', 'kacang', 'barley']; 

emptyArray = []; 

month_lengths = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; 

slide = [
    {url: 'slide0001.html', judul: 'Menatap ke Depan'},
    {url: 'slide0008.html', judul: 'Forecast'},
    {url: 'slide0021.html', judul: 'Ringkasan' }
];

Sebuah item baru dapat ditambahkan ke array oleh tugas.

a [i + j] = f (a [i], sebuah [j]);

fungsi

Fungsi dalam JavaScript terlihat seperti fungsi C, kecuali bahwa mereka dinyatakan dengan fungsi kata kunci bukan tipe. Saat memanggil fungsi, itu tidak diperlukan bahwa Anda melewati sejumlah tetap parameter. Parameter kelebihan diabaikan. Hilang parameter diberi nilai terdefinisi . Hal ini membuat mudah untuk menulis fungsi yang berhubungan dengan argumen opsional.

Sebuah fungsi memiliki akses ke argumen array yang. Ini berisi semua parameter yang benar-benar dikirim oleh pemanggil. Itu membuat mudah untuk menangani fungsi mengambil sejumlah variabel argumen. Sebagai contoh,

fungsi sum () {// Ambil sejumlah parameter dan mengembalikan jumlah
    keseluruhan var = 0;
    for (var i = 0; i <arguments.length; ++ i) {
        jumlah + = argumen [i];
    }
    Kembali jumlah;
}

JavaScript memiliki fungsi batin, yang melayani tujuan yang sama seperti kelas batin di Jawa, tetapi jauh lebih ringan. JavaScript juga memiliki fungsi anonim, yang bertindak sebagai ekspresi lambda. Fungsi memiliki scoping leksikal.

Fungsi adalah objek kelas pertama dalam JavaScript. Itu berarti bahwa mereka dapat disimpan dalam objek dan lulus sebagai argumen untuk fungsi.

 

Definisi

Ada tiga notasi untuk fungsi mendefinisikan: pernyataan fungsi, operator fungsi, dan fungsi konstruktor.

fungsi pernyataan

Pernyataan Fungsi menciptakan fungsi bernama dalam lingkup saat ini.

Fungsi nama argumentlist blok

Fungsi dapat bersarang. Lihat Penutup. Sebuah argumentlist adalah nol atau lebih argumen nama, dipisahkan dengan koma. Sebuah blok adalah daftar nol atau lebih pernyataan tertutup dalam {} .

Pernyataan fungsi adalah singkatan untuk bentuk Operator fungsi:

var nama = function nama argumentlist blok ;

fungsi Operator

Operator fungsi operator awalan yang menghasilkan fungsi objek. Ini terlihat mirip dengan pernyataan fungsi.

Fungsi nama argumentlist blok

The Nama adalah opsional. Jika disediakan, maka dapat digunakan oleh tubuh fungsi untuk memanggil dirinya secara rekursif. Hal ini juga dapat digunakan untuk mengakses anggota objek fungsi ini (kecuali pada IE). Jika nama tersebut dihilangkan, maka itu adalah fungsi anonim.

Operator fungsi umumnya digunakan untuk menetapkan fungsi untuk prototipe.

Operator fungsi juga dapat digunakan untuk menentukan fungsi di tempat, yang berguna ketika menulis callback.

fungsi konstruktor

Fungsi konstruktor mengambil string yang berisi argumen dan tubuh, dan menghasilkan fungsi objek.

Fungsi baru ( string ... )

Jangan gunakan formulir ini. Konvensi mengutip dari bahasa membuatnya sangat sulit untuk benar mengekspresikan fungsi tubuh sebagai string. Dalam bentuk string, awal pengecekan error tidak dapat dilakukan. Hal ini lambat karena compiler harus dipanggil setiap kali konstruktor disebut. Dan itu adalah boros memori karena setiap fungsi memerlukan implementasi sendiri independen.

Objek dan ini

Sebuah fungsi adalah obyek. Hal ini dapat berisi anggota hanya sebagai objek lainnya. Hal ini memungkinkan fungsi untuk mengandung tabel data sendiri. Hal ini juga memungkinkan sebuah objek untuk bertindak sebagai kelas , yang berisi konstruktor dan seperangkat metode yang terkait.

Sebuah fungsi dapat menjadi anggota dari sebuah objek. Ketika fungsi adalah anggota dari sebuah objek, itu disebut metode . Ada variabel khusus, yang disebut ini yang diatur untuk objek ketika metode objek disebut.

Misalnya, dalam ekspresi foo.bar () , yang ini variabel diatur ke objek foo sebagai semacam argumen tambahan untuk fungsi bar . Fungsi bar kemudian dapat merujuk iniuntuk mengakses objek yang menarik.

Dalam ekspresi yang lebih dalam seperti do.re.mi.fa () , yang ini variabel diatur ke objek do.re.mi , bukan ke objek lakukan . Dalam fungsi panggilan sederhana, inidiatur ke Obyek global (alias window ), yang tidak sangat berguna. Perilaku yang benar seharusnya untuk melestarikan nilai saat ini , terutama saat memanggil fungsi batin.

pembina

Fungsi yang digunakan untuk menginisialisasi objek yang disebut konstruktor . Urutan menyerukan konstruktor sedikit berbeda dibandingkan fungsi biasa. Sebuah konstruktor disebut dengan baru awalan:

baru Constructor parameter ... )

Dengan konvensi, nama konstruktor ditulis dengan modal awal.

The baru awalan mengubah arti dari ini variabel. Alih-alih nilai yang biasa, ini akan menjadi objek baru. Tubuh fungsi konstruktor biasanya akan menginisialisasi anggota objek. Konstruktor akan mengembalikan objek baru, kecuali secara eksplisit ditimpa dengan kembali pernyataan.

Objek dibangun akan berisi bidang prototipe tautan rahasia, yang berisi referensi ke konstruktor prototipe anggota.

prototype

Objek berisi properti tautan tersembunyi. Link ini menunjuk pada prototipe anggota dari konstruktor objek.

Ketika item diakses dari sebuah objek dengan notasi dot atau notasi subscript, jika item tidak ditemukan dalam objek maka objek link diperiksa. Jika tidak ditemukan dalam objek tautan, dan jika objek link itu sendiri memiliki objek tautan, maka objek link yang diperiksa. Jika rantai link benda habis, maka tidak terdefinisi dikembalikan.

Ini menggunakan rantai prototipe Link menyediakan semacam warisan.

Anggota dapat ditambahkan ke prototipe oleh tugas. Di sini kita mendefinisikan kelas baru Demo , yang mewarisi dari kelas leluhur , dan menambahkan metode sendiri foo .

Fungsi Demo () {}
Demo.prototype = baru Leluhur ();
Demo.prototype.foo = function () {};

yang

Variabel bernama didefinisikan dengan var pernyataan. Ketika digunakan dalam fungsi, var mendefinisikan variabel dengan fungsi-lingkup . Vars tidak dapat diakses dari luar fungsi. Tidak ada rincian lain dari lingkup dalam JavaScript. Secara khusus, tidak ada blok-lingkup .

Setiap variabel yang digunakan dalam fungsi yang tidak secara eksplisit didefinisikan sebagai var diasumsikan milik sebuah lingkup luar, mungkin ke Obyek global.

Vars yang tidak secara eksplisit diinisialisasi diberi nilai terdefinisi .

Vars tidak diketik. Sebuah var dapat berisi referensi ke suatu objek, atau string atau angka atau boolean atau nol atau tidak terdefinisi .

Sebuah set baru vars dibuat setiap kali fungsi ini dipanggil. Hal ini memungkinkan fungsi menjadi rekursif.

Penutupan

Fungsi dapat didefinisikan di dalam fungsi lainnya. Fungsi batin memiliki akses ke vars dan parameter dari fungsi luar. Jika referensi ke fungsi dalam bertahan (misalnya, sebagai fungsi callback), vars fungsi luar juga bertahan hidup.

Kembali

JavaScript tidak memiliki kekosongan jenis, sehingga setiap fungsi harus mengembalikan nilai. Nilai default adalah tidak terdefinisi , kecuali konstruktor, di mana nilai default kembali adalah ini .

laporan

Set laporan bernama termasuk var , jika , saklar , untuk , sementara , lakukan , istirahat , terus , pulang , mencoba , melempar , dan dengan . Sebagian besar dari mereka bekerja sama dengan dalam bahasa C-seperti lainnya.

The var pernyataan adalah daftar dari satu atau lebih variabel nama, dipisahkan dengan koma, dengan ekspresi inisialisasi opsional.

var a, b = window.document.body;

Jika var pernyataan muncul di luar fungsi apapun, itu menambah anggota untuk Object global. Jika muncul dalam fungsi, mendefinisikan variabel lokal dari fungsi.

Dalam jika pernyataan, sementara laporan, melakukan laporan, dan operator logika, JavaScript memperlakukan palsu , nol , tidak terdefinisi , "" (string kosong), dan nomor 0 sebagai palsu. Semua nilai-nilai lain diperlakukan sebagai benar .

The kasus label dalam saklar pernyataan dapat ekspresi. Mereka tidak harus konstanta. Mereka bisa string.

Ada dua bentuk dari untuk pernyataan. Yang pertama adalah umum (init ; tes ; inc) bentuk. Yang kedua adalah iterator objek.

untuk (nama dalam objek) {
    if (object.hasOwnProperty (nama)) {
        value = objek [nama];
    }
}

Blok dijalankan untuk setiap nama dalam objek . Urutan nama-nama diproduksi tidak dijamin.

Laporan dapat memiliki awalan label, yang merupakan identifier yang diikuti dengan titik dua.

The dengan pernyataan tidak boleh digunakan.

operator

JavaScript memiliki seperangkat cukup besar operator. Sebagian besar dari mereka bekerja dengan cara yang sama seperti dalam bahasa C-seperti lainnya. Ada beberapa perbedaan yang harus diperhatikan.

The + operator yang digunakan untuk kedua penambahan dan penggabungan. Jika salah satu operan adalah string, itu merangkai. Hal ini dapat menyebabkan kesalahan.Misalnya, '$' + 3 + 4 menghasilkan '$ 34' , bukan '$ 7' .

+ Dapat digunakan sebagai operator awalan, mengkonversi operan string nya ke angka.

!! dapat digunakan sebagai operator awalan, mengkonversi operan untuk boolean.

The && operator biasa disebut logis dan . Hal ini juga dapat disebut penjaga . Jika operan pertama adalah palsu , nol , tidak terdefinisi , "" (string kosong), atau jumlah 0maka kembali operan pertama. Jika tidak, ia mengembalikan operan kedua. Ini menyediakan cara yang nyaman untuk menulis null-cek:

nilai var = p && p.name; / * Nilai nama akan
hanya diambil dari p jika p memiliki nilai, menghindari kesalahan. * /

The || Operator yang biasa disebut logis atau . Hal ini juga dapat disebut standar . Jika operan pertama adalah palsu , nol , tidak terdefinisi , "" (string kosong), atau nomor 0 , maka kembali operan kedua. Jika tidak, ia mengembalikan operan pertama. Ini menyediakan cara yang nyaman untuk menentukan nilai default:

value = v || 10; / * Gunakan nilai v, tetapi jika v
tidak memiliki nilai, menggunakan 10 sebagai gantinya. * /

JavaScript memasok satu set bitwise dan pergeseran operator, tetapi tidak memiliki jenis Integer untuk menerapkannya. Apa yang terjadi adalah Nomor operan (64-bit angka floating-point) dikonversi menjadi integer 32-bit sebelum operasi, dan kemudian dikonversi kembali ke floating point setelah operasi.

Dalam JavaScript, kekosongan adalah operator awalan, bukan tipe. Selalu kembali terdefinisi . Ini memiliki nilai yang sangat kecil. Saya hanya menyebutkan dalam kasus Anda tidak sengaja mengetik kekosongan dari kebiasaan dan bingung dengan perilaku aneh.

The typeof Operator mengembalikan sebuah string berdasarkan jenis operan nya.

Kesalahan yang dibuat.

Obyek 'obyek'
susunan 'obyek'
Fungsi 'fungsi'
Tali 'tali'
Jumlah 'jumlah'
boolean 'Boolean'
batal 'obyek'
tidak terdefinisi 'tidak terdefinisi'

Bunga rampai

Obyek global

Objek global adalah penjaga semua fungsi dan variabel yang tidak didefinisikan di dalam fungsi dan benda-benda lainnya. Anehnya, Objek global tidak memiliki nama eksplisit dalam bahasa. Kadang-kadang ini poin variabel itu, tetapi sering tidak. Dalam web browser, jendela dan diri adalah anggota dari Object global yang menunjuk ke Object Global, sehingga memberikan cara tidak langsung menangani itu.

Jika variabel diakses, tapi tidak ditemukan dalam lingkup saat ini, itu tampak dalam Object global. Jika tidak ditemukan di sana, kesalahan akan menghasilkan.

Spesifikasi ECMAScript tidak berbicara tentang kemungkinan beberapa objek Global, atau konteks , tapi browser mendukung ini. Setiap jendela memiliki Obyek global sendiri.

Titik koma Penyisipan

Salah satu kesalahan dalam bahasa adalah penyisipan titik koma. Ini adalah teknik untuk membuat titik koma opsional sebagai terminator pernyataan. Hal ini wajar untuk IDE dan program shell untuk melakukan penyisipan titik koma. Hal ini tidak masuk akal untuk definisi bahasa untuk meminta kompiler untuk melakukannya. Gunakan titik koma.

Kata-kata milik

JavaScript sangat berat diserahkan pembatasan pada kata-kata reserved. Kata-kata reserved yang

abstrak 
boolean istirahat byte 
kasus tangkapan kelas const char terus
debugger bawaan menghapus melakukan ganda 
lain ekspor enum meluas 
palsu akhir akhirnya mengapung untuk fungsi
goto 
jika alat mengimpor di instanceof int antarmuka 
lama 
asli nol baru
paket pribadi yang terlindungi publik 
pulang
singkat yang super statis saklar disinkronkan 
ini melempar melempar transient benar mencoba typeof 
var stabil kekosongan 
sementara dengan

Sebagian besar dari kata-kata yang bahkan tidak digunakan dalam bahasa. Sebuah kata reserved tidak dapat digunakan

  1. Sebagai nama dalam notasi objek literal
  2. Sebagai nama anggota di titik notasi
  3. Sebagai argumen fungsi
  4. Sebagai var
  5. Sebagai variabel global wajar tanpa pengecualian
  6. Sebagai label pernyataan

Tidak ada alasan untuk dua pembatasan pertama. Tidak ada. Ada alasan untuk kedua dua pembatasan, tapi sangat lemah.