Bagian ini memberikan sedikit latar belakang tentang JavaScript untuk membantu Anda memahami mengapa hal itu seperti itu.
ECMAScript adalah nama resmi untuk JavaScript. Nama baru menjadi perlu karena ada merek dagang pada JavaScript (yang dimiliki pada awalnya oleh Sun, sekarang oleh Oracle). Saat ini, Mozilla adalah salah satu dari sedikit perusahaan yang diizinkan untuk secara resmi menggunakan nama JavaScript karena telah menerima lisensi lama yang lalu.
Pencipta JavaScript, Brendan Eich, tidak punya pilihan selain membuat bahasa dengan sangat cepat (atau teknologi lain yang lebih buruk akan diadopsi oleh Netscape). ia meminjam dari beberapa bahasa pemrograman: Java (sintaksis, nilai primitif versus objek), Scheme dan AWK (fungsi kelas pertama), Self (warisan prototipe), dan Perl dan Python (string, array, dan ekspresi reguler).
JavaScript tidak memiliki penanganan pengecualian sampai ECMAScript 3, yang menjelaskan mengapa bahasa sering secara otomatis mengkonversi nilai dan sering gagal diam-diam: awalnya tidak bisa membuang pengecualian.
Di satu sisi, JavaScript memiliki keanehan dan tidak memiliki sedikit fungsi (variabel ruang lingkup blok, modul, dukungan untuk subclassing, dll.). Di sisi lain, ia memiliki beberapa fitur kuat yang memungkinkan Anda untuk mengatasi masalah ini. Dalam bahasa lain, Anda belajar fitur bahasa. Dalam JavaScript, Anda sering belajar pola sebagai gantinya.
Mengingat pengaruhnya, tidak mengherankan bahwa JavaScript memungkinkan gaya pemrograman yang merupakan campuran pemrograman fungsional (fungsi orde lebih tinggi; built-in map, reduce, dll.) dan pemrograman berorientasi objek (objek, warisan).
Bagian ini menjelaskan prinsip sintaksis dasar JavaScript.
Beberapa contoh sintaksis:
// Two slashes start single-line comments
var x; // declaring a variable
x = 3 + y; // assigning a value to the variable `x`
foo(x, y); // calling function `foo` with parameters `x` and `y`
obj.bar(3); // calling method `bar` of object `obj`
// A conditional statement
if (x === 0) { // Is `x` equal to zero?
x = 123;
}
// Defining function `baz` with parameters `a` and `b`
function baz(a, b) {
return a + b;
}
Perhatikan dua penggunaan yang berbeda dari tanda sama:
Untuk memahami sintaksis JavaScript, Anda harus tahu bahwa ia memiliki dua kategori sintaksis utama: pernyataan dan ekspresi:
var foo;
3 * 7
Perbedaan antara pernyataan dan ekspresi paling jelas dengan fakta bahwa JavaScript memiliki dua cara berbeda untuk melakukan if-then-else
var x;
if (y >= 0) {
x = y;
} else {
x = -y;
}
atau sebagai ungkapan:
var x = y >= 0 ? y : -y;
Anda dapat menggunakan yang terakhir sebagai argumen fungsi (tetapi tidak yang pertama):
myFunction(y >= 0 ? y : -y)
Akhirnya, di mana saja JavaScript mengharapkan pernyataan, Anda juga dapat menggunakan ekspresi; misalnya:
foo(7, 1);
Seluruh garis adalah pernyataan (yang disebut pernyataan ekspresi), tetapi panggilan fungsi foo ((7, 1) adalah ekspresi.
Semikolon adalah opsional dalam JavaScript. Namun, saya merekomendasikan selalu menyertakan mereka, karena jika tidak JavaScript dapat menebak salah tentang akhir pernyataan. Rinciannya dijelaskan dalam Automatic Semicolon Insertion.
Semikolon mengakhiri pernyataan, tetapi tidak blok. Ada satu kasus di mana Anda akan melihat semikolon setelah blok: ekspresi fungsi adalah ekspresi yang berakhir dengan blok. Jika ekspresi seperti itu datang terakhir dalam pernyataan, itu diikuti oleh semikolon:
// Pattern: var _ = ___;
var x = 3 * 7;
var f = function () { }; // function expr. inside var decl.
JavaScript memiliki dua jenis komentar: komentar satu baris dan komentar multi baris. Komentar satu baris dimulai dengan // dan diakhiri pada akhir baris:
x++; // single-line comment
Komentar multiline dibatasi oleh /* dan */:
/* This is
a multiline
comment.
*/
Variabel dalam JavaScript dinyatakan sebelum digunakan:
var foo; // declare variable `foo`
Anda dapat mendeklarasikan variabel dan menetapkan nilai pada saat yang sama:
var foo = 6;
Anda juga dapat menetapkan nilai untuk variabel yang ada:
foo = 4; // change variable `foo`
Ada operator penugasan senyawa seperti +=. Dua penugasan berikut setara:
x += 1;
x = x + 1;
Identifier adalah nama yang memainkan berbagai peran sintaksis dalam JavaScript. Misalnya, nama variabel adalah identifier.
Secara kasar, karakter pertama dari pengenal dapat menjadi huruf Unicode, tanda dolar ($), atau tanda bawah (_).
arg0
_tmp
$elem
π
Identifier berikut adalah kata-kata yang disediakan
Tiga identifier berikut ini bukan kata-kata yang disediakan, tetapi Anda harus memperlakukan mereka seolah-olah mereka:
Akhirnya, Anda juga harus menjauh dari nama variabel global standar. Anda dapat menggunakannya untuk variabel lokal tanpa merusak apa pun, tetapi kode Anda masih menjadi membingungkan.
JavaScript memiliki banyak nilai yang kita harapkan dari bahasa pemrograman: boolean, angka, string, array, dan sebagainya. Semua nilai dalam JavaScript memiliki properti. Setiap properti memiliki kunci (atau nama) dan nilai. Anda dapat menganggap properti seperti bidang catatan. Anda menggunakan operator titik (.) untuk membaca properti:
value.propKey
Misalnya, string
> var str = 'abc';
> str.length
3
Yang sebelumnya juga bisa ditulis sebagai:
> 'abc'.length
3
The dot operator is also used to assign a value to a property:
> var obj = {}; // empty object
> obj.foo = 123; // create property `foo`, set it to 123
123
> obj.foo
123
Dan Anda dapat menggunakannya untuk memanggil metode:
> 'hello'.toUpperCase()
'HELLO'
Dalam contoh sebelumnya, kita telah memanggil metode toUpperCase() pada nilai
JavaScript membuat perbedaan yang agak sewenang-wenang antara nilai:
> var obj1 = {}; // an empty object
> var obj2 = {}; // another empty object
> obj1 === obj2
false
> obj1 === obj1
true
Sebaliknya, semua nilai primitif yang mengkodekan nilai yang sama dianggap sama:
> var prim1 = 123;
> var prim2 = 123;
> prim1 === prim2
true
Dua bagian berikutnya menjelaskan nilai-nilai dan objek primitif secara lebih rinci.
Berikut adalah semua nilai primitif (atau primitives untuk pendek):
Primitif memiliki karakteristik berikut:
> 3 === 3
true
> 'abc' === 'abc'
true
###Selalu tidak berubah Properti tidak dapat diubah, ditambahkan, atau dihapus:
> var str = 'abc';
> str.length = 1; // try to change property `length`
> str.length // ⇒ no effect
3
> str.foo = 3; // try to create property `foo`
> str.foo // ⇒ no effect, unknown property
undefined
(Membaca properti yang tidak diketahui selalu mengembalikan undefined.)
Semua nilai nonprimitif adalah objek. Jenis objek yang paling umum adalah:
{
firstName: 'Jane',
lastName: 'Doe'
}
Objek sebelumnya memiliki dua properti: nilai properti firstName adalah
[ 'apple', 'banana', 'cherry' ]
Array sebelumnya memiliki tiga elemen yang dapat diakses melalui indeks numerik.
/^a+b+$/
Objek memiliki karakteristik berikut:
Identitas dibandingkan; setiap nilai memiliki identitasnya sendiri:
> ({} === {}) // two different empty objects
false
> var obj1 = {};
> var obj2 = obj1;
> obj1 === obj2
true
Anda biasanya dapat secara bebas mengubah, menambahkan, dan menghapus properti (lihat Objek Tunggal):
> var obj = {};
> obj.foo = 123; // add property `foo`
> obj.foo
123
Sebagian besar bahasa pemrograman memiliki nilai yang menunjukkan informasi yang hilang.
> var foo;
> foo
undefined
Parameter yang hilang tidak ditentukan:
> function f(x) { return x }
> f()
undefined
Jika Anda membaca properti yang tidak ada, Anda mendapatkan tidak didefinisikan:
> var obj = {}; // empty object
> obj.foo
undefined
undefined dan null tidak memiliki properti, bahkan metode standar seperti toString().
Fungsi biasanya memungkinkan Anda untuk menunjukkan nilai yang hilang baik melalui undefined atau null. Anda dapat melakukan hal yang sama melalui pemeriksaan eksplisit:
if (x === undefined || x === null) {
...
}
Anda juga dapat memanfaatkan fakta bahwa baik undefined dan null dianggap palsu:
if (!x) {
...
}
false, 0, NaN, dan
Ada dua operator untuk mengkategorikan nilai: typeof terutama digunakan untuk nilai primitif, sementara instanceof digunakan untuk objek. bentuknya seperti ini:
typeof value
Ini mengembalikan string yang menggambarkan
> typeof true
'boolean'
> typeof 'abc'
'string'
> typeof {} // empty object literal
'object'
> typeof [] // empty array literal
'object'
Tabel berikut mencantumkan semua hasil dari tipe:
typeof null returning
Contoh ini terlihat seperti ini:
value instanceof Constr
Hal ini mengembalikan benar jika nilai adalah objek yang telah dibuat oleh konstruktor Constr (lihat Konstruktor: Pabrik untuk Objek).
> var b = new Bar(); // object created by constructor Bar
> b instanceof Bar
true
> {} instanceof Object
true
> [] instanceof Array
true
> [] instanceof Object // Array is a subconstructor of Object
true
> undefined instanceof Object
false
> null instanceof Object
false
Tipe boolean primitif terdiri dari nilai true dan false. Operator berikut menghasilkan boolean:
Setiap kali JavaScript mengharapkan nilai boolean (misalnya, untuk kondisi pernyataan if), nilai apa pun dapat digunakan. Ini akan ditafsirkan sebagai benar atau salah. Nilai berikut ditafsirkan sebagai salah:
Semua nilai lainnya (termasuk semua objek!) dianggap benar. Nilai yang ditafsirkan sebagai salah disebut palsu, dan nilai yang ditafsirkan sebagai benar disebut benar. Boolean ((), yang disebut sebagai fungsi, mengkonversi parameternya menjadi boolean. Anda dapat menggunakannya untuk menguji bagaimana nilai ditafsirkan:
> Boolean(undefined)
false
> Boolean(0)
false
> Boolean(3)
true
> Boolean({}) // empty object
true
> Boolean([]) // empty array
true
Operator logis biner dalam JavaScript adalah short-circuit. yaitu, jika operand pertama cukup untuk menentukan hasilnya, operand kedua tidak dievaluasi. misalnya dalam ekspresi berikut, fungsi foo() tidak pernah disebut:
false && foo()
true || foo()
Selain itu, operator logis biner mengembalikan salah satu operand mereka, yang mungkin atau mungkin bukan boolean.
Jika operand pertama salah, kembalikan. Jika tidak, kembalikan operand kedua:
> NaN && 'abc'
NaN
> 123 && 'abc'
'abc'
Jika operand pertama benar, kembalikan. Jika tidak, kembalikan operand kedua:
> 'abc' || 123
'abc'
> '' || 123
123
JavaScript memiliki dua jenis kesetaraan:
Persamaan normal menganggap (terlalu) banyak nilai sama (detailnya dijelaskan dalam Persamaan Normal (Lenient) (==,!=)), yang dapat menyembunyikan bug.
Semua angka dalam JavaScript adalah titik terapung:
> 1 === 1.0
true
Nomor khusus termasuk yang berikut:
NaN (
> Number('xyz') // 'xyz' can’t be converted to a number
NaN
Tak terbatas. Juga sebagian besar nilai kesalahan:
> 3 / 0
Infinity
> Math.pow(2, 1024) // number too large
Infinity
Infinity lebih besar dari bilangan lain (kecuali NaN). Demikian pula, -Infinity lebih kecil dari bilangan lain (kecuali NaN). Yang membuat angka-angka ini berguna sebagai nilai default (misalnya, ketika Anda mencari minimum atau maksimum).
JavaScript memiliki operator aritmatika berikut (lihat Operator Aritmatika):
Objek global Matematika (lihat Matematika) menyediakan operasi aritmatika yang lebih banyak, melalui fungsi.
JavaScript juga memiliki operator untuk operasi bitwise (misalnya, bitwise And; lihat Operator Bitwise).
String dapat dibuat secara langsung melalui string literals. Literal tersebut dibatasi oleh tanda kutip tunggal atau ganda. Backslash () menghindari karakter dan menghasilkan beberapa karakter kontrol. Berikut adalah beberapa contoh:
'abc'
"abc"
'Did she say "Hello"?'
"Did she say \"Hello\"?"
'That\'s nice!'
"That's nice!"
'Line 1\nLine 2' // newline
'Backlash: \\'
Karakter tunggal diakses melalui kurung persegi:
> var str = 'abc';
> str[1]
'b'
Properti panjang menghitung jumlah karakter dalam string:
> 'abc'.length
3
Seperti semua primitif, string tidak dapat diubah; Anda perlu membuat string baru jika Anda ingin mengubah yang sudah ada.
Senar digabungkan melalui operator plus (+), yang mengubah operand lain menjadi string jika salah satu operand adalah string:
> var messageCount = 3;
> 'You have ' + messageCount + ' messages'
'You have 3 messages'
Untuk mengikat string dalam beberapa langkah, gunakan operator +=:
> var str = '';
> str += 'Multiple ';
> str += 'pieces ';
> str += 'are concatenated.';
> str
'Multiple pieces are concatenated.'
String memiliki banyak metode yang berguna (lihat String Prototype Methods). Berikut adalah beberapa contoh:
> 'abc'.slice(1) // copy a substring
'bc'
> 'abc'.slice(1, 2)
'b'
> '\t xyz '.trim() // trim whitespace
'xyz'
> 'mjölnir'.toUpperCase()
'MJÖLNIR'
> 'abc'.indexOf('b') // find a string
1
> 'abc'.indexOf('x')
-1
Kondisi dan loop dalam JavaScript diperkenalkan dalam bagian berikut.
Pernyataan if memiliki klausa then dan klausa else opsional yang dieksekusi tergantung pada kondisi boolean:
if (myvar === 0) {
// then
}
if (myvar === 0) {
// then
} else {
// else
}
if (myvar === 0) {
// then
} else if (myvar === 1) {
// else-if
} else if (myvar === 2) {
// else-if
} else {
// else
}
Saya merekomendasikan selalu menggunakan kurung (mereka menunjukkan blok nol atau lebih pernyataan). Tapi Anda tidak perlu melakukannya jika klausa hanya satu pernyataan (sama berlaku untuk perintah aliran kontrol untuk dan sementara):
if (x < 0) return -x;
Berikut ini adalah perintah switch. Nilai buah menentukan kasus mana yang akan dieksekusi:
switch (fruit) {
case 'banana':
// ...
break;
case 'apple':
// ...
break;
default: // all other cases
// ...
}
For loop memiliki format sebagai berikut:
for (⟦«init»⟧; ⟦«condition»⟧; ⟦«post_iteration»⟧)
«statement»
init dieksekusi pada awal loop. kondisi diperiksa sebelum setiap iterasi loop; jika menjadi false, maka loop diakhiri. post_iteration dieksekusi setelah setiap iterasi loop.
Contoh ini mencetak semua elemen array arr di konsol:
for (var i=0; i < arr.length; i++) {
console.log(arr[i]);
}
Sementara loop terus looping di tubuhnya sementara kondisinya memegang:
// Same as for loop above:
var i = 0;
while (i < arr.length) {
console.log(arr[i]);
i++;
}
Do-while loop terus berputar di atas tubuhnya sementara kondisinya bertahan.
do {
// ...
} while (condition);
Di semua loop:
Salah satu cara untuk mendefinisikan fungsi adalah melalui deklarasi fungsi:
function add(param1, param2) {
return param1 + param2;
}
Kode sebelumnya mendefinisikan fungsi, add, yang memiliki dua parameter, param1 dan param2, dan mengembalikan jumlah kedua parameter.
> add(6, 1)
7
> add('a', 'b')
'ab'
Cara lain untuk mendefinisikan add() adalah dengan menetapkan ekspresi fungsi ke variabel add:
var add = function (param1, param2) {
return param1 + param2;
};
Ekspresi fungsi menghasilkan nilai dan dengan demikian dapat digunakan untuk langsung melewati fungsi sebagai argumen ke fungsi lain:
someOtherFunction(function (p1, p2) { ... });
Deklarasi fungsi ditinggikan dan dipindahkan secara keseluruhan ke awal ruang lingkup saat ini.
function foo() {
bar(); // OK, bar is hoisted
function bar() {
...
}
}
Perhatikan bahwa sementara deklarasi var juga diangkat (lihat Variabel Diangkat), tugas yang dilakukan oleh mereka tidak:
function foo() {
bar(); // Not OK, bar is still undefined
var bar = function () {
// ...
};
}
Anda dapat memanggil fungsi apa pun di JavaScript dengan jumlah arbitrer argumen; bahasa tidak akan pernah mengeluh. Namun, itu akan membuat semua parameter tersedia melalui argumen variabel khusus. argumen terlihat seperti array, tetapi tidak memiliki metode array:
> function f() { return arguments }
> var args = f('a', 'b', 'c');
> args.length
3
> args[0] // read element at index 0
'a'
Mari kita gunakan fungsi berikut untuk mengeksplorasi bagaimana terlalu banyak atau terlalu sedikit parameter ditangani dalam JavaScript (fungsi toArray( ditunjukkan dalam Mengkonversi argumen ke Array):
function f(x, y) {
console.log(x, y);
return toArray(arguments);
}
Parameter tambahan akan diabaikan (kecuali oleh argumen):
> f('a', 'b', 'c')
a b
[ 'a', 'b', 'c' ]
Parameter yang hilang akan membuat nilai tidak didefinisikan:
> f('a')
a undefined
[ 'a' ]
> f()
undefined undefined
[]
Berikut adalah pola umum untuk menetapkan nilai default untuk parameter:
function pair(x, y) {
x = x || 0; // (1)
y = y || 0;
return [ x, y ];
}
Dalam baris (1), operator yang dimaksudkan mengembalikan x jika benar (bukan nol, tidak ditentukan, dll.).
> pair()
[ 0, 0 ]
> pair(3)
[ 3, 0 ]
> pair(3, 5)
[ 3, 5 ]
Jika Anda ingin memaksakan arity (jumlah parameter tertentu), Anda dapat memeriksa arguments.length:
function pair(x, y) {
if (arguments.length !== 2) {
throw new Error('Need exactly 2 arguments');
}
...
}
arguments bukanlah array, itu hanya array-like (lihat Array-Like Objects and Generic Methods). Ini memiliki panjang properti, dan Anda dapat mengakses elemen-elemennya melalui indeks dalam kurung persegi. Anda tidak dapat, bagaimanapun, menghapus elemen atau memanggil salah satu metode array di atasnya. Dengan demikian, Anda kadang-kadang perlu mengkonversi argumen ke array, yang merupakan fungsi berikut (dijelaskan dalam Array-Like Objects and Generic Methods):
function toArray(arrayLikeObject) {
return Array.prototype.slice.call(arrayLikeObject);
}
Cara yang paling umum untuk menangani pengecualian (lihat Bab 14) adalah sebagai berikut:
function getPerson(id) {
if (id < 0) {
throw new Error('ID must not be negative: '+id);
}
return { id: id }; // normally: retrieved from database
}
function getPersons(ids) {
var result = [];
ids.forEach(function (id) {
try {
var person = getPerson(id);
result.push(person);
} catch (exception) {
console.log(exception);
}
});
return result;
}
Try clause mengelilingi kode kritis, dan catch clause dieksekusi jika suatu pengecualian dilemparkan ke dalam try clause.
> getPersons([2, -5, 137])
[Error: ID must not be negative: -5]
[ { id: 2 }, { id: 137 } ]
Strict Mode (lihat Strict Mode) memungkinkan lebih banyak peringatan dan membuat JavaScript menjadi bahasa yang lebih bersih (nonstrict mode kadang-kadang disebut
'use strict';
Anda juga dapat mengaktifkan modus ketat per fungsi:
function functionInStrictMode() {
'use strict';
}
Dalam JavaScript, Anda mendeklarasikan variabel melalui var sebelum menggunakannya:
> var x;
> x
undefined
> y
ReferenceError: y is not defined
Anda dapat mendeklarasikan dan menginisialisasi beberapa variabel dengan satu pernyataan var:
var x = 1, y = 2, z = 3;
Tapi saya sarankan menggunakan satu pernyataan per variabel (alasan dijelaskan dalam sintaksis).
var x = 1;
var y = 2;
var z = 3;
Karena hoisting (lihat Variables Are Hoisted), biasanya yang terbaik adalah mendeklarasikan variabel di awal fungsi.
Lingkup variabel selalu fungsi lengkap (sebagai lawan dari blok saat ini).
function foo() {
var x = -512;
if (x < 0) { // (1)
var tmp = -x;
...
}
console.log(tmp); // 512
}
Kita dapat melihat bahwa variabel tmp tidak terbatas pada blok yang dimulai di baris (1); itu ada sampai akhir fungsi.
Setiap deklarasi variabel diangkat: deklarasi dipindahkan ke awal fungsi, tetapi penugasan yang dibuatnya tetap ditempatkan.
function foo() {
console.log(tmp); // undefined
if (false) {
var tmp = 3; // (1)
}
}
Secara internal, fungsi sebelumnya dijalankan seperti ini:
function foo() {
var tmp; // hoisted declaration
console.log(tmp);
if (false) {
tmp = 3; // assignment stays put
}
}
Setiap fungsi tetap terhubung dengan variabel dari fungsi yang mengelilinginya, bahkan setelah meninggalkan ruang lingkup di mana ia dibuat.
function createIncrementor(start) {
return function () { // (1)
start++;
return start;
}
}
Fungsi yang dimulai di baris (1) meninggalkan konteks di mana ia dibuat, tetapi tetap terhubung ke versi hidup dari start:
> var inc = createIncrementor(5);
> inc()
6
> inc()
7
> inc()
8
Penutupan adalah fungsi ditambah koneksi ke variabel dari lingkup sekitarnya.
Kadang-kadang Anda ingin memperkenalkan ruang lingkup variabel baru, misalnya, untuk mencegah variabel menjadi global. Dalam JavaScript, Anda tidak dapat menggunakan blok untuk melakukannya; Anda harus menggunakan fungsi. Tetapi ada pola untuk menggunakan fungsi dengan cara seperti blok. Ini disebut IIFE (ekspresi fungsi yang dipanggil segera, diucapkan
(function () { // open IIFE
var tmp = ...; // not a global variable
}()); // close IIFE
Pastikan untuk mengetikkan contoh sebelumnya persis seperti yang ditunjukkan (selain komentar). IIFE adalah ekspresi fungsi yang dipanggil segera setelah Anda mendefinisikannya. Di dalam fungsi, ruang lingkup baru ada, mencegah tmp menjadi global. Lihat Memperkenalkan Lingkup Baru melalui IIFE untuk rincian tentang IIFE.
Penutupan menjaga koneksi mereka ke variabel eksternal, yang kadang-kadang tidak apa yang Anda inginkan:
var result = [];
for (var i=0; i < 5; i++) {
result.push(function () { return i }); // (1)
}
console.log(result[1]()); // 5 (not 1)
console.log(result[3]()); // 5 (not 3)
Nilai yang dikembalikan pada baris (1) selalu merupakan nilai saat ini dari i, bukan nilai yang dimiliki saat fungsi dibuat. Setelah loop selesai, i memiliki nilai 5, itulah sebabnya semua fungsi dalam array mengembalikan nilai itu. Jika Anda ingin fungsi pada baris (1) untuk menerima snapshot dari nilai saat ini dari i, Anda dapat menggunakan IIFE:
for (var i=0; i < 5; i++) {
(function () {
var i2 = i; // copy current i
result.push(function () { return i2 });
}());
}
Bagian ini mencakup dua mekanisme berbasis objek dasar dari JavaScript: objek tunggal dan konstruktor (yang merupakan pabrik untuk objek, mirip dengan kelas dalam bahasa lain).
Seperti semua nilai, objek memiliki sifat. Anda dapat, pada kenyataannya, menganggap objek sebagai seperangkat sifat, di mana setiap properti adalah pasangan (kunci, nilai). Kunci adalah string, dan nilainya adalah nilai JavaScript apa pun.
Dalam JavaScript, Anda dapat langsung membuat objek biasa, melalui literal objek:
'use strict';
var jane = {
name: 'Jane',
describe: function () {
return 'Person named '+this.name;
}
};
Objek sebelumnya memiliki sifat nama dan deskripsi. Anda dapat membaca (
> jane.name // get
'Jane'
> jane.name = 'John'; // set
> jane.newProperty = 'abc'; // property created automatically
Fungsi-nilai properti seperti describe disebut metode. Mereka menggunakan ini untuk merujuk pada objek yang digunakan untuk memanggil mereka:
> jane.describe() // call method
'Person named John'
> jane.name = 'Jane';
> jane.describe()
'Person named Jane'
Operator in memeriksa apakah properti ada:
> 'newProperty' in jane
true
> 'foo' in jane
false
Jika Anda membaca properti yang tidak ada, Anda mendapatkan nilai undefined. Oleh karena itu dua pemeriksaan sebelumnya juga bisa dilakukan seperti ini:
> jane.newProperty !== undefined
true
> jane.foo !== undefined
false
Operator hapus menghapus properti:
> delete jane.newProperty
true
> 'newProperty' in jane
false
Kata kunci properti dapat menjadi string apa pun. Sejauh ini, kita telah melihat kata kunci properti dalam literal objek dan setelah operator titik. Namun, Anda hanya dapat menggunakannya dengan cara itu jika mereka adalah pengidentifikasi (lihat Identifier dan Nama Variabel). Jika Anda ingin menggunakan string lain sebagai kunci, Anda harus mengutip mereka dalam literal objek dan menggunakan tanda kurung persegi untuk mendapatkan dan mengatur properti:
> var obj = { 'not an identifier': 123 };
> obj['not an identifier']
123
> obj['not an identifier'] = 456;
Keranjang persegi juga memungkinkan Anda untuk menghitung kunci properti:
> var obj = { hello: 'world' };
> var x = 'hello';
> obj[x]
'world'
> obj['hel'+'lo']
'world'
Jika Anda mengekstrak suatu metode, maka fungsi tersebut kehilangan koneksi dengan objeknya.
Sebagai contoh, mari kita kembali ke objek Jane sebelumnya:
'use strict';
var jane = {
name: 'Jane',
describe: function () {
return 'Person named '+this.name;
}
};
Kita ingin mengekstrak metode describe dari jane, menaruhnya ke dalam variabel func, dan memanggilnya.
> var func = jane.describe;
> func()
TypeError: Cannot read property 'name' of undefined
Solusinya adalah menggunakan metode bind() yang dimiliki semua fungsi.
> var func2 = jane.describe.bind(jane);
> func2()
'Person named Jane'
Setiap fungsi memiliki variabel khusus sendiri ini. Ini tidak nyaman jika Anda nest fungsi di dalam metode, karena Anda tidak dapat mengakses metode ini dari fungsi. Berikut ini adalah contoh di mana kita memanggil forEach dengan fungsi untuk diulang di atas array:
var jane = {
name: 'Jane',
friends: [ 'Tarzan', 'Cheeta' ],
logHiToFriends: function () {
'use strict';
this.friends.forEach(function (friend) {
// `this` is undefined here
console.log(this.name+' says hi to '+friend);
});
}
}
Menelpon logHiToFriends menghasilkan kesalahan:
> jane.logHiToFriends()
TypeError: Cannot read property 'name' of undefined
Mari kita lihat dua cara untuk memperbaiki ini. pertama, kita bisa menyimpan ini dalam variabel yang berbeda:
logHiToFriends: function () {
'use strict';
var that = this;
this.friends.forEach(function (friend) {
console.log(that.name+' says hi to '+friend);
});
}
Atau, forEach memiliki parameter kedua yang memungkinkan Anda untuk memberikan nilai untuk ini:
logHiToFriends: function () {
'use strict';
this.friends.forEach(function (friend) {
console.log(this.name+' says hi to '+friend);
}, this);
}
Ekspresi fungsi sering digunakan sebagai argumen dalam panggilan fungsi dalam JavaScript. Selalu berhati-hati ketika Anda merujuk ini dari salah satu dari ekspresi fungsi tersebut.
Hingga saat ini, Anda mungkin berpikir bahwa objek JavaScript hanya peta dari string ke nilai, sebuah gagasan yang disarankan oleh literal objek JavaScript, yang terlihat seperti peta / literal kamus bahasa lain. Namun, objek JavaScript juga mendukung fitur yang benar-benar berorientasi objek: pewarisan. Bagian ini tidak sepenuhnya menjelaskan bagaimana pewarisan JavaScript bekerja, tetapi menunjukkan pola sederhana untuk memulai. Lihat Bab 17 jika Anda ingin tahu lebih lanjut.
Selain fungsi dan metode, fungsi memainkan peran lain dalam JavaScript: mereka menjadi konstruktor untuk objek jika dipanggil melalui operator baru. Konstruktor adalah analog kasar untuk kelas dalam bahasa lain.
// Set up instance data
function Point(x, y) {
this.x = x;
this.y = y;
}
// Methods
Point.prototype.dist = function () {
return Math.sqrt(this.x*this.x + this.y*this.y);
};
Kita dapat melihat bahwa konstruktor memiliki dua bagian. Pertama, fungsi Point mengatur data instance. Kedua, properti Point.prototype berisi objek dengan metode. Data yang pertama spesifik untuk setiap instance, sementara data terakhir dibagi di antara semua instance.
Untuk menggunakan Point, kita memanggilnya melalui operator baru:
> var p = new Point(3, 5);
> p.x
3
> p.dist()
5.830951894845301
p adalah contoh dari Point:
> p instanceof Point
true
Array adalah urutan elemen yang dapat diakses melalui indeks bilangan bulat mulai dari nol.
Array literals berguna untuk membuat array:
> var arr = [ 'a', 'b', 'c' ];
Array sebelumnya memiliki tiga elemen: string
> arr[0]
'a'
> arr[0] = 'x';
> arr
[ 'x', 'b', 'c' ]
Properti panjang menunjukkan berapa banyak elemen array memiliki. Anda dapat menggunakannya untuk menambahkan elemen dan untuk menghapus elemen:
> var arr = ['a', 'b'];
> arr.length
2
> arr[arr.length] = 'c';
> arr
[ 'a', 'b', 'c' ]
> arr.length
3
> arr.length = 1;
> arr
[ 'a' ]
Operator in bekerja untuk array juga:
> var arr = [ 'a', 'b', 'c' ];
> 1 in arr // is there an element at index 1?
true
> 5 in arr // is there an element at index 5?
false
Perhatikan bahwa array adalah objek dan dengan demikian dapat memiliki sifat objek:
> var arr = [];
> arr.foo = 123;
> arr.foo
123
Array memiliki banyak metode (lihat Array Prototype Methods). Berikut adalah beberapa contoh:
> var arr = [ 'a', 'b', 'c' ];
> arr.slice(1, 2) // copy elements
[ 'b' ]
> arr.slice(1)
[ 'b', 'c' ]
> arr.push('x') // append an element
4
> arr
[ 'a', 'b', 'c', 'x' ]
> arr.pop() // remove last element
'x'
> arr
[ 'a', 'b', 'c' ]
> arr.shift() // remove first element
'a'
> arr
[ 'b', 'c' ]
> arr.unshift('x') // prepend an element
3
> arr
[ 'x', 'b', 'c' ]
> arr.indexOf('b') // find the index of an element
1
> arr.indexOf('y')
-1
> arr.join('-') // all elements in a single string
'x-b-c'
> arr.join('')
'xbc'
> arr.join()
'x,b,c'
Ada beberapa metode array untuk mengulangi elemen (lihat Iterasi (Tidak merusak)). Dua yang paling penting adalah forEach dan peta.
forEach mengulangi array dan menyerahkan elemen saat ini dan indeksnya ke fungsi:
[ 'a', 'b', 'c' ].forEach(
function (elem, index) { // (1)
console.log(index + '. ' + elem);
});
Kode sebelumnya menghasilkan output berikut:
0. a
1. b
2. c
Perhatikan bahwa fungsi pada baris (1) bebas untuk mengabaikan argumen.
map membuat array baru dengan menerapkan fungsi ke setiap elemen array yang ada:
> [1,2,3].map(function (x) { return x*x })
[ 1, 4, 9 ]
JavaScript memiliki dukungan bawaan untuk ekspresi reguler.
/^abc$/
/[A-Za-z0-9]+/
> /^a+b+$/.test('aaab')
true
> /^a+b+$/.test('aaa')
false
> /a(b+)a/.exec('_abbba_aba_')
[ 'abbba', 'bbb' ]
Array yang dikembalikan berisi pencocokan lengkap pada indeks 0, penangkapan kelompok pertama pada indeks 1, dan sebagainya. Ada cara (dibahas di RegExp.prototype.exec: Capture Groups) untuk memanggil metode ini berulang kali untuk mendapatkan semua pencocokan.
> '<a> <bbb>'.replace(/<(.*?)>/g, '[$1]')
'[a] [bbb]'
Parameter pertama dari replace harus menjadi ekspresi reguler dengan bendera /g; jika tidak, hanya kejadian pertama yang diganti.
Matematika adalah objek dengan fungsi aritmatika. Berikut adalah beberapa contoh:
> Math.abs(-2)
2
> Math.pow(3, 2) // 3 to the power of 2
9
> Math.max(2, -1, 5)
5
> Math.round(1.9)
2
> Math.PI // pre-defined constant for π
3.141592653589793
> Math.cos(Math.PI) // compute the cosine for 180°
-1