4.1 Bahasa JavaScript awal cepat

Penulis:Kebaikan, Dibuat: 2019-04-26 11:46:12, Diperbarui: 2019-04-27 11:53:43

Latar belakang

Bagian ini memberikan sedikit latar belakang tentang JavaScript untuk membantu Anda memahami mengapa hal itu seperti itu.

JavaScript Versus ECMAScript

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.

  • JavaScript berarti bahasa pemrograman.
  • ECMAScript adalah nama yang digunakan oleh spesifikasi bahasa. Oleh karena itu, setiap kali mengacu pada versi bahasa, orang mengatakan ECMAScript. Versi JavaScript saat ini adalah ECMAScript 5; ECMAScript 6 saat ini sedang dikembangkan.

Pengaruh dan Sifat Bahasa

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).

Sintaks

Bagian ini menjelaskan prinsip sintaksis dasar JavaScript.

Tinjauan Sintaks

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:

  • Tanda sama tunggal (=) digunakan untuk menetapkan nilai pada variabel.
  • Tanda tiga sama (===) digunakan untuk membandingkan dua nilai (lihat Operator Kesetaraan).

Pernyataan Melawan Ekspresi

Untuk memahami sintaksis JavaScript, Anda harus tahu bahwa ia memiliki dua kategori sintaksis utama: pernyataan dan ekspresi:

  • Pernyataan do things. Program adalah urutan pernyataan. Berikut adalah contoh pernyataan, yang menyatakan (menciptakan) variabel foo:
var foo;
  • Ekspresi menghasilkan nilai. Mereka adalah argumen fungsi, sisi kanan dari penugasan, dll. Berikut adalah contoh ekspresi:
3 * 7

Perbedaan antara pernyataan dan ekspresi paling jelas dengan fakta bahwa JavaScript memiliki dua cara berbeda untuk melakukan if-then-else baik sebagai pernyataan:

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

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.

Komentar

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 dan Penugasan

Variabel dalam JavaScript dinyatakan sebelum digunakan:

var foo;  // declare variable `foo`

Penugasan

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`

Operator Penugasan Senyawa

Ada operator penugasan senyawa seperti +=. Dua penugasan berikut setara:

x += 1;
x = x + 1;

Identifier dan nama variabel

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 disediakanmereka adalah bagian dari sintaksis dan tidak dapatdigunakan sebagai nama variabel (termasuk nama fungsi dan nama parameter):

img

Tiga identifier berikut ini bukan kata-kata yang disediakan, tetapi Anda harus memperlakukan mereka seolah-olah mereka:

img

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.

Nilai-nilai

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 abc memiliki panjang properti:

> 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 hello.

Nilai-Nilai Primitif Melawan Objek

JavaScript membuat perbedaan yang agak sewenang-wenang antara nilai:

  • Nilai primitif adalah boolean, angka, string, null, dan undefined.
  • Semua nilai lainnya adalah objek. Perbedaan utama antara keduanya adalah bagaimana mereka dibandingkan; setiap objek memiliki identitas yang unik dan hanya (sangat sama dengan dirinya sendiri):
> 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.

Nilai-Nilai Primitif

Berikut adalah semua nilai primitif (atau primitives untuk pendek):

  • Boolean: benar, salah (lihat Boolean)
  • Angka: 1736, 1.351 (lihat Angka)
  • Senar: abc, abc (lihat Senar)
  • Dua nonvalues: undefined, null (lihat undefined dan null)

Primitif memiliki karakteristik berikut:

Dibandingkan dengan nilai

isi dibandingkan:

> 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.)

Objek

Semua nilai nonprimitif adalah objek. Jenis objek yang paling umum adalah:

  • Objek biasa, yang dapat dibuat oleh objek literal (lihat Objek Tunggal):
{
    firstName: 'Jane',
    lastName: 'Doe'
}

Objek sebelumnya memiliki dua properti: nilai properti firstName adalah Jane dan nilai properti lastName adalah Doe.

  • Array, yang dapat dibuat oleh array literals (lihat Arrays):
[ 'apple', 'banana', 'cherry' ]

Array sebelumnya memiliki tiga elemen yang dapat diakses melalui indeks numerik.

  • Ekspresi reguler, yang dapat dibuat oleh literal ekspresi reguler (lihat Ekspresi reguler):
/^a+b+$/

Objek memiliki karakteristik berikut:

Dibandingkan dengan referensi

Identitas dibandingkan; setiap nilai memiliki identitasnya sendiri:

> ({} === {})  // two different empty objects
false

> var obj1 = {};
> var obj2 = obj1;
> obj1 === obj2
true

Bisa diubah secara default

Anda biasanya dapat secara bebas mengubah, menambahkan, dan menghapus properti (lihat Objek Tunggal):

> var obj = {};
> obj.foo = 123; // add property `foo`
> obj.foo
123

tidak terdefinisi dan nol

Sebagian besar bahasa pemrograman memiliki nilai yang menunjukkan informasi yang hilang.

  • undefined berarti tidak ada nilai. Variabel yang tidak diinitialisasi tidak didefinisikan:
> 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
  • null berarti tidak ada objek. Ini digunakan sebagai nonvalue setiap kali sebuah objek diharapkan (parameter, terakhir dalam rantai objek, dll).

Peringatan

undefined dan null tidak memiliki properti, bahkan metode standar seperti toString().

Memeriksa undefined atau null

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) {
    ...
}

Peringatan

false, 0, NaN, dan juga dianggap palsu (lihat Truthy dan Falsy).

Mengkategorikan Nilai Menggunakan jenis dan contoh

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 type nilai. Berikut adalah beberapa contoh:

> typeof true
'boolean'
> typeof 'abc'
'string'
> typeof {} // empty object literal
'object'
> typeof [] // empty array literal
'object'

Tabel berikut mencantumkan semua hasil dari tipe:

img

typeof null returning object adalah bug yang tidak dapat diperbaiki, karena akan merusak kode yang ada.

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

Boolean

Tipe boolean primitif terdiri dari nilai true dan false. Operator berikut menghasilkan boolean:

  • Operator logis biner: && (Dan),
  • Operator logis awalan:! (Tidak)
  • Operator perbandingan: Operator kesetaraan: ===,!==, ==,!=
  • Operator pemesanan (untuk string dan angka): >, >=, <, <=

Benar dan Palsu

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:

  • tidak terdefinisi, nol
  • Boolean: false
  • Jumlah: 0, NaN
  • String:

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 Logika Biner

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.

Dan (&&)

Jika operand pertama salah, kembalikan. Jika tidak, kembalikan operand kedua:

> NaN && 'abc'
NaN
> 123 && 'abc'
'abc'

Atau (kamu)

Jika operand pertama benar, kembalikan. Jika tidak, kembalikan operand kedua:

> 'abc' || 123
'abc'
> '' || 123
123

Operator Kesetaraan

JavaScript memiliki dua jenis kesetaraan:

  • Normal, atau lembut, (tidak sama): == dan!=
  • Strict (in) equality: === dan!==

Persamaan normal menganggap (terlalu) banyak nilai sama (detailnya dijelaskan dalam Persamaan Normal (Lenient) (==,!=)), yang dapat menyembunyikan bug.

Angka

Semua angka dalam JavaScript adalah titik terapung:

> 1 === 1.0
true

Nomor khusus termasuk yang berikut:

NaN (bukan angka) Nilai kesalahan:

> 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).

Operator

JavaScript memiliki operator aritmatika berikut (lihat Operator Aritmatika):

  • Penjumlahan: nomor1 + nomor2
  • Pengurangan: nomor 1 - nomor 2
  • Perkalian: nomor1 * nomor2
  • Divisi: nomor 1 / nomor 2
  • Sisanya: nomor 1 % nomor 2
  • Increment: ++variabel, variabel++
  • Decrement: variabel, variabel
  • Negatif: -nilai
  • Konversi ke nomor: + nilai

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

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.

Operator string

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.'

Metode string

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

Pernyataan

Kondisi dan loop dalam JavaScript diperkenalkan dalam bagian berikut.

Kondisi

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
        // ...
}

operand setelah kasus dapat menjadi ekspresi apapun; itu dibandingkan melalui === dengan parameter switch.

Loop

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:

  • putus meninggalkan lingkaran.
  • Lanjutkan memulai iterasi loop baru.

Fungsi

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 Diangkat

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 () {
        // ...
    };
}

Argumen Variabel Khusus

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'

Terlalu Banyak atau Terlalu Sedikit Perdebatan

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
[]

Parameter Opsional

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 ]

Memaksakan Keadilan

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');
    }
    ...
}

Mengkonversi argumen ke Array

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);
}

Penanganan Pengecualian

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 } ]

Modus ketat

Strict Mode (lihat Strict Mode) memungkinkan lebih banyak peringatan dan membuat JavaScript menjadi bahasa yang lebih bersih (nonstrict mode kadang-kadang disebut sloppy mode).

'use strict';

Anda juga dapat mengaktifkan modus ketat per fungsi:

function functionInStrictMode() {
    'use strict';
}

Lingkup Variabel dan Penutupan

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.

Variabel Berfungsi

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.

Variabel Diangkat

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
    }
}

Penutupan

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.

Pola IIFE: Memperkenalkan Lingkup Baru

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 iffy):

(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.

Kasus penggunaan IIFE: pembagian tidak sengaja melalui penutupan

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 });
    }());
}

Objek dan Konstruktor

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).

Tujuan Tunggal

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 (get) dan menulis (set) properti:

> 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

Kunci Properti Sewenang-wenang

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'

Metode Ekstraksi

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'

Fungsi Dalam Metode

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.

Pembuat: Pabrik untuk Objek

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

Array adalah urutan elemen yang dapat diakses melalui indeks bilangan bulat mulai dari nol.

Array Literals

Array literals berguna untuk membuat array:

> var arr = [ 'a', 'b', 'c' ];

Array sebelumnya memiliki tiga elemen: string a, b, dan c. Anda dapat mengaksesnya melalui indeks bilangan bulat:

> 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

Metode Array

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'

Iterasi atas Array

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 ]

Ekspresi Reguler

JavaScript memiliki dukungan bawaan untuk ekspresi reguler.

/^abc$/
/[A-Za-z0-9]+/

Tes metode: Apakah ada yang cocok?

> /^a+b+$/.test('aaab')
true
> /^a+b+$/.test('aaa')
false

Metode exec ((): Pasang dan menangkap kelompok

> /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.

Metode replace ((): Cari dan Ganti

> '<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

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

Lebih banyak