Bahagian ini memberikan sedikit latar belakang tentang JavaScript untuk membantu anda memahami mengapa ia adalah cara ia.
ECMAScript adalah nama rasmi untuk JavaScript. Nama baru menjadi perlu kerana terdapat tanda dagangan pada JavaScript (yang dimiliki pada asalnya oleh Sun, kini oleh Oracle). Pada masa ini, Mozilla adalah salah satu daripada beberapa syarikat yang dibenarkan menggunakan nama JavaScript secara rasmi kerana ia menerima lesen lama yang lalu.
Pencipta JavaScript, Brendan Eich, tidak mempunyai pilihan selain membuat bahasa ini dengan sangat cepat (atau teknologi lain yang lebih buruk akan diterima pakai oleh Netscape). Dia meminjam dari beberapa bahasa pengaturcaraan: Java (sintaks, nilai primitif berbanding objek), Skema dan AWK (fungsi kelas pertama), Self (warisan prototaip), dan Perl dan Python (string, array, dan ungkapan tetap).
JavaScript tidak mempunyai pengendalian pengecualian sehingga ECMAScript 3, yang menjelaskan mengapa bahasa itu sering menukar nilai secara automatik dan sering gagal secara senyap: pada mulanya tidak dapat membuang pengecualian.
Di satu pihak, JavaScript mempunyai ciri-ciri dan tidak mempunyai sedikit fungsi (variabel ruang lingkup blok, modul, sokongan untuk subkelas, dan lain-lain). Di sisi lain, ia mempunyai beberapa ciri yang kuat yang membolehkan anda mengatasi masalah ini. Dalam bahasa lain, anda belajar ciri bahasa. Dalam JavaScript, anda sering belajar corak sebaliknya.
Memandangkan pengaruhnya, tidak menghairankan bahawa JavaScript membolehkan gaya pengaturcaraan yang merupakan campuran pengaturcaraan fungsional (fungsi peringkat tinggi; peta terbina dalam, mengurangkan, dll.) dan pengaturcaraan berorientasikan objek (objek, warisan).
Bahagian ini menerangkan prinsip sintaksis asas JavaScript.
Beberapa contoh sintaks:
// 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 kegunaan berbeza tanda sama:
Untuk memahami sintaks JavaScript, anda harus tahu bahawa ia mempunyai dua kategori sintaksis utama: pernyataan dan ungkapan:
var foo;
3 * 7
Perbezaan antara pernyataan dan ungkapan paling jelas dengan fakta bahawa JavaScript mempunyai dua cara yang berbeza 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 boleh menggunakan yang terakhir sebagai argumen fungsi (tetapi bukan yang pertama):
myFunction(y >= 0 ? y : -y)
Akhirnya, di mana sahaja JavaScript mengharapkan pernyataan, anda juga boleh menggunakan ungkapan; contohnya:
foo(7, 1);
Seluruh baris adalah pernyataan (yang dipanggil pernyataan ungkapan), tetapi panggilan fungsi foo ((7, 1) adalah ungkapan.
Semikolon adalah pilihan dalam JavaScript. Walau bagaimanapun, saya mengesyorkan sentiasa memasukkannya, kerana jika tidak JavaScript boleh menebak salah mengenai akhir pernyataan. butiran dijelaskan dalam Automatic Semicolon Insertion.
Semikolon menamatkan pernyataan, tetapi bukan blok. Terdapat satu kes di mana anda akan melihat semikolon selepas blok: ungkapan fungsi adalah ungkapan yang berakhir dengan blok. Jika ungkapan sedemikian datang terakhir dalam pernyataan, ia diikuti dengan semikolon:
// Pattern: var _ = ___;
var x = 3 * 7;
var f = function () { }; // function expr. inside var decl.
JavaScript mempunyai dua jenis komen: komen satu baris dan komen berbilang baris. Komen satu baris bermula dengan // dan diakhiri pada akhir baris:
x++; // single-line comment
Komen berbilang baris dibatasi oleh /* dan */:
/* This is
a multiline
comment.
*/
Pemboleh ubah dalam JavaScript diisytiharkan sebelum digunakan:
var foo; // declare variable `foo`
Anda boleh mengisytiharkan pembolehubah dan menetapkan nilai pada masa yang sama:
var foo = 6;
Anda juga boleh menetapkan nilai kepada pembolehubah sedia ada:
foo = 4; // change variable `foo`
Terdapat pengendali penugasan gabungan seperti +=. Dua penugasan berikut adalah bersamaan:
x += 1;
x = x + 1;
Pengiktirafan adalah nama yang memainkan pelbagai peranan sintaksis dalam JavaScript. Sebagai contoh, nama pembolehubah adalah pengiktirafan.
Secara kasar, aksara pertama pengenal boleh menjadi sebarang huruf Unicode, tanda dolar ($), atau tanda bawah (_).
arg0
_tmp
$elem
π
Pengiktirafan berikut adalah perkataan yang dikhaskan
Tiga pengenal berikut bukan perkataan yang disediakan, tetapi anda harus memperlakukan mereka seolah-olah mereka:
Akhirnya, anda juga harus menjauhkan diri dari nama-nama pembolehubah global standard. anda boleh menggunakannya untuk pembolehubah tempatan tanpa memecahkan apa-apa, tetapi kod anda masih menjadi mengelirukan.
JavaScript mempunyai banyak nilai yang kita harapkan dari bahasa pengaturcaraan: boolean, nombor, rentetan, array, dan sebagainya. Semua nilai dalam JavaScript mempunyai sifat. Setiap sifat mempunyai kunci (atau nama) dan nilai. Anda boleh memikirkan sifat seperti medan rekod. Anda menggunakan operator titik (.) untuk membaca sifat:
value.propKey
Sebagai contoh, rentetan
> var str = 'abc';
> str.length
3
Yang terdahulu juga boleh 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 boleh menggunakannya untuk memanggil kaedah:
> 'hello'.toUpperCase()
'HELLO'
Dalam contoh sebelumnya, kita telah memanggil kaedah toUpperCase() pada nilai
JavaScript membuat perbezaan 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 mengkodkan nilai yang sama dianggap sama:
> var prim1 = 123;
> var prim2 = 123;
> prim1 === prim2
true
Dua bahagian seterusnya menerangkan nilai dan objek primitif dengan lebih terperinci.
Berikut adalah semua nilai primitif (atau primitif untuk pendek):
Primitif mempunyai ciri-ciri berikut:
> 3 === 3
true
> 'abc' === 'abc'
true
### Selalu tidak berubah Ciri-ciri tidak boleh diubah, ditambah, atau dikeluarkan:
> 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 sifat yang tidak diketahui sentiasa mengembalikan tidak ditakrifkan.)
Semua nilai bukan primitif adalah objek. Jenis objek yang paling biasa ialah:
{
firstName: 'Jane',
lastName: 'Doe'
}
Objek sebelumnya mempunyai dua sifat: nilai sifat firstName adalah
[ 'apple', 'banana', 'cherry' ]
Array sebelumnya mempunyai tiga elemen yang boleh diakses melalui indeks nombor. Sebagai contoh, indeks
/^a+b+$/
Objek mempunyai ciri-ciri berikut:
Identiti dibandingkan; setiap nilai mempunyai identiti sendiri:
> ({} === {}) // two different empty objects
false
> var obj1 = {};
> var obj2 = obj1;
> obj1 === obj2
true
Anda biasanya boleh bebas mengubah, menambah, dan membuang sifat (lihat Objek Tunggal):
> var obj = {};
> obj.foo = 123; // add property `foo`
> obj.foo
123
Kebanyakan bahasa pengaturcaraan mempunyai nilai yang menunjukkan maklumat yang hilang. JavaScript mempunyai dua jenis
> var foo;
> foo
undefined
Parameter yang hilang tidak ditakrifkan:
> function f(x) { return x }
> f()
undefined
Jika anda membaca harta yang tidak wujud, anda mendapat tidak ditakrifkan:
> var obj = {}; // empty object
> obj.foo
undefined
undefined dan null tidak mempunyai sifat, bahkan kaedah standard seperti toString().
Fungsi biasanya membolehkan anda untuk menunjukkan nilai yang hilang melalui sama ada tidak ditakrifkan atau sifar.
if (x === undefined || x === null) {
...
}
Anda juga boleh mengeksploitasi hakikat bahawa kedua-dua tidak ditakrifkan dan sifar dianggap salah:
if (!x) {
...
}
false, 0, NaN, dan
Terdapat dua pengendali untuk mengkategorikan nilai: typeof digunakan terutamanya untuk nilai primitif, manakala instanceof digunakan untuk objek. jenis ini kelihatan seperti ini:
typeof value
Ia mengembalikan rentetan yang menggambarkan
> typeof true
'boolean'
> typeof 'abc'
'string'
> typeof {} // empty object literal
'object'
> typeof [] // empty array literal
'object'
Jadual berikut menyenaraikan semua hasil jenis:
Contoh ini kelihatan seperti ini:
value instanceof Constr
Ia mengembalikan benar jika nilai adalah objek yang telah dicipta oleh pembina Constr (lihat pembina: kilang untuk objek). Berikut adalah beberapa contoh:
> 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
Jenis boolean primitif terdiri daripada nilai benar dan palsu. Operator berikut menghasilkan boolean:
Setiap kali JavaScript mengharapkan nilai boolean (contohnya, untuk syarat pernyataan if), mana-mana nilai boleh digunakan. Ia akan ditafsirkan sebagai benar atau salah. Nilai berikut ditafsirkan sebagai salah:
Semua nilai lain (termasuk semua objek!) dianggap benar. Nilai yang ditafsirkan sebagai palsu dipanggil palsu, dan nilai yang ditafsirkan sebagai benar dipanggil benar. Boolean ((), dipanggil sebagai fungsi, menukar parameternya kepada boolean. Anda boleh menggunakannya untuk menguji bagaimana nilai ditafsirkan:
> Boolean(undefined)
false
> Boolean(0)
false
> Boolean(3)
true
> Boolean({}) // empty object
true
> Boolean([]) // empty array
true
Operator logik binari dalam JavaScript adalah litar pendek. iaitu, jika operand pertama mencukupi untuk menentukan hasilnya, operand kedua tidak dinilai. Sebagai contoh, dalam ungkapan berikut, fungsi foo() tidak pernah dipanggil:
false && foo()
true || foo()
Selain itu, pengendali logik binari mengembalikan salah satu operand mereka
Jika operand pertama adalah salah, kembalikan. Jika tidak, kembalikan operand kedua:
> NaN && 'abc'
NaN
> 123 && 'abc'
'abc'
Jika operand pertama adalah benar, kembalikan. Jika tidak, kembalikan operand kedua:
> 'abc' || 123
'abc'
> '' || 123
123
JavaScript mempunyai dua jenis kesamaan:
Kesamaan normal menganggap (terlalu) banyak nilai sama (perinciannya dijelaskan dalam Kesamaan Normal (==,!=)), yang boleh menyembunyikan bug. Oleh itu, selalu menggunakan kesamaan yang ketat disyorkan.
Semua nombor dalam JavaScript adalah titik terapung:
> 1 === 1.0
true
Nombor khas termasuk yang berikut:
NaN (
> Number('xyz') // 'xyz' can’t be converted to a number
NaN
Tak terhingga Juga kebanyakannya nilai ralat:
> 3 / 0
Infinity
> Math.pow(2, 1024) // number too large
Infinity
Infinity lebih besar daripada nombor lain (kecuali NaN). Begitu juga, -Infinity lebih kecil daripada nombor lain (kecuali NaN). Itu menjadikan nombor ini berguna sebagai nilai lalai (contohnya, apabila anda mencari minimum atau maksimum).
JavaScript mempunyai pengendali aritmatika berikut (lihat Operator Aritmatika):
Objek global Matematika (lihat Matematika) menyediakan lebih banyak operasi aritmatika, melalui fungsi.
JavaScript juga mempunyai operator untuk operasi bitwise (contohnya, bitwise And; lihat Operator Bitwise).
String boleh dicipta secara langsung melalui literals string. literals tersebut dibatasi oleh tanda petikan tunggal atau berganda. backslash () melepaskan aksara dan menghasilkan beberapa aksara kawalan. 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: \\'
Tanda tunggal diakses melalui kurung persegi:
> var str = 'abc';
> str[1]
'b'
Panjang sifat mengira bilangan aksara dalam rentetan:
> 'abc'.length
3
Seperti semua primitif, rentetan tidak berubah; anda perlu membuat rentetan baru jika anda ingin mengubah yang sedia ada.
Senar disatukan melalui operator tambah (+), yang menukar operand lain kepada senar jika salah satu operand adalah senar:
> var messageCount = 3;
> 'You have ' + messageCount + ' messages'
'You have 3 messages'
Untuk mengikat rentetan dalam beberapa langkah, gunakan operator +=:
> var str = '';
> str += 'Multiple ';
> str += 'pieces ';
> str += 'are concatenated.';
> str
'Multiple pieces are concatenated.'
String mempunyai banyak kaedah 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
Syarat dan gelung dalam JavaScript diperkenalkan dalam bahagian berikut.
Perkataan if mempunyai klausa then dan klausa else pilihan yang dilaksanakan bergantung pada keadaan 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 mengesyorkan sentiasa menggunakan kurung (mereka menunjukkan blok sifar atau lebih pernyataan). tetapi anda tidak perlu melakukannya jika klausa hanya satu pernyataan (sama berlaku untuk control flow pernyataan untuk dan sementara):
if (x < 0) return -x;
Nilai buah menentukan kes mana yang akan dilaksanakan:
switch (fruit) {
case 'banana':
// ...
break;
case 'apple':
// ...
break;
default: // all other cases
// ...
}
Garis pusingan for mempunyai format berikut:
for (⟦«init»⟧; ⟦«condition»⟧; ⟦«post_iteration»⟧)
«statement»
init dijalankan pada permulaan gelung. keadaan diperiksa sebelum setiap pengulangan gelung; jika menjadi salah, maka gelung diakhiri. post_iteration dijalankan selepas setiap pengulangan gelung.
Contoh ini mencetak semua elemen array arr pada konsol:
for (var i=0; i < arr.length; i++) {
console.log(arr[i]);
}
Lemparan sementara terus mengelilingi tubuhnya selagi kondisinya berlaku:
// Same as for loop above:
var i = 0;
while (i < arr.length) {
console.log(arr[i]);
i++;
}
Lutung do-while terus berlusuk di atas tubuhnya sementara kondisinya bertahan.
do {
// ...
} while (condition);
Dalam semua gelung:
Salah satu cara untuk menentukan fungsi adalah melalui pengisytiharan fungsi:
function add(param1, param2) {
return param1 + param2;
}
Kod sebelum ini menentukan fungsi, tambah, yang mempunyai dua parameter, param1 dan param2, dan mengembalikan jumlah kedua-dua parameter.
> add(6, 1)
7
> add('a', 'b')
'ab'
Cara lain untuk menentukan add (() adalah dengan menetapkan ungkapan fungsi kepada pembolehubah add:
var add = function (param1, param2) {
return param1 + param2;
};
Ungkapan fungsi menghasilkan nilai dan dengan itu boleh digunakan untuk terus menyampaikan fungsi sebagai argumen kepada fungsi lain:
someOtherFunction(function (p1, p2) { ... });
Perisytiharan fungsi diangkat
function foo() {
bar(); // OK, bar is hoisted
function bar() {
...
}
}
Perhatikan bahawa walaupun pengisytiharan var juga diangkat (lihat Peralihan Diangkat), tugasan yang dilakukan oleh mereka tidak:
function foo() {
bar(); // Not OK, bar is still undefined
var bar = function () {
// ...
};
}
Anda boleh memanggil mana-mana fungsi dalam JavaScript dengan jumlah argumen yang sewenang-wenang; bahasa tidak akan pernah mengadu.
> 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 meneroka bagaimana terlalu banyak atau terlalu sedikit parameter ditangani dalam JavaScript (fungsi toArray( ditunjukkan dalam Mengubah 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 mendapatkan nilai tidak ditakrifkan:
> f('a')
a undefined
[ 'a' ]
> f()
undefined undefined
[]
Berikut adalah corak biasa untuk menetapkan nilai lalai kepada parameter:
function pair(x, y) {
x = x || 0; // (1)
y = y || 0;
return [ x, y ];
}
Dalam baris (1), pengendali bersambung mengembalikan x jika ia adalah benar (bukan sifar, tidak ditakrifkan, dan lain-lain).
> pair()
[ 0, 0 ]
> pair(3)
[ 3, 0 ]
> pair(3, 5)
[ 3, 5 ]
Jika anda ingin menguatkuasakan arity (sebilangan tertentu parameter), anda boleh memeriksa arguments.length:
function pair(x, y) {
if (arguments.length !== 2) {
throw new Error('Need exactly 2 arguments');
}
...
}
arguments bukanlah array, ia hanya seperti array (lihat Array-Like Objects and Generic Methods). Ia mempunyai panjang sifat, dan anda boleh mengakses elemen-elemennya melalui indeks dalam kurungan persegi. Anda tidak boleh, bagaimanapun, membuang elemen atau memanggil mana-mana kaedah array di atasnya. Oleh itu, kadang-kadang anda perlu menukar 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 biasa untuk menangani pengecualian (lihat Bab 14) adalah seperti 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;
}
Klausa cuba mengelilingi kod kritikal, dan klausa menangkap dilaksanakan jika pengecualian dilemparkan di dalam klausa cuba.
> getPersons([2, -5, 137])
[Error: ID must not be negative: -5]
[ { id: 2 }, { id: 137 } ]
Mod ketat (lihat Mod ketat) membolehkan lebih banyak amaran dan menjadikan JavaScript bahasa yang lebih bersih (mod tidak ketat kadang-kadang dipanggil