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
'use strict';
Anda juga boleh mengaktifkan mod ketat setiap fungsi:
function functionInStrictMode() {
'use strict';
}
Dalam JavaScript, anda mengisytiharkan pembolehubah melalui var sebelum menggunakannya:
> var x;
> x
undefined
> y
ReferenceError: y is not defined
Anda boleh mengisytiharkan dan memulakan beberapa pembolehubah dengan satu pernyataan var:
var x = 1, y = 2, z = 3;
Tetapi saya mengesyorkan menggunakan satu pernyataan bagi setiap pembolehubah (alasan dijelaskan dalam sintaks).
var x = 1;
var y = 2;
var z = 3;
Oleh kerana pengangkatan (lihat Variables Are Hoisted), biasanya lebih baik untuk mengisytiharkan pembolehubah pada permulaan fungsi.
Lingkup pembolehubah sentiasa fungsi lengkap (berbeza dengan blok semasa).
function foo() {
var x = -512;
if (x < 0) { // (1)
var tmp = -x;
...
}
console.log(tmp); // 512
}
Kita dapat melihat bahawa pembolehubah tmp tidak terhad kepada blok yang bermula dalam baris (1); ia wujud sehingga akhir fungsi.
Setiap pengisytiharan pembolehubah diangkat: pengisytiharan dipindahkan ke awal fungsi, tetapi tugasan yang dibuatnya tetap diletakkan.
function foo() {
console.log(tmp); // undefined
if (false) {
var tmp = 3; // (1)
}
}
Secara dalaman, fungsi sebelumnya dilaksanakan seperti ini:
function foo() {
var tmp; // hoisted declaration
console.log(tmp);
if (false) {
tmp = 3; // assignment stays put
}
}
Setiap fungsi kekal berkaitan dengan pembolehubah fungsi yang mengelilinginya, walaupun selepas ia meninggalkan skop di mana ia dicipta.
function createIncrementor(start) {
return function () { // (1)
start++;
return start;
}
}
Fungsi yang bermula di baris (1) meninggalkan konteks di mana ia dicipta, tetapi kekal disambungkan ke versi hidup permulaan:
> var inc = createIncrementor(5);
> inc()
6
> inc()
7
> inc()
8
Penutupan adalah fungsi ditambah sambungan kepada pembolehubah skop sekitarnya.
Kadang-kadang anda ingin memperkenalkan skop pembolehubah baru
(function () { // open IIFE
var tmp = ...; // not a global variable
}()); // close IIFE
Pastikan anda menaip contoh sebelumnya seperti yang ditunjukkan (selain komen). IIFE adalah ungkapan fungsi yang dipanggil segera selepas anda tentukan. Di dalam fungsi, skop baru wujud, menghalang tmp daripada menjadi global. Sila rujuk Memperkenalkan skop baru melalui IIFE untuk butiran mengenai IIFEs.
Penutupan menyimpan sambungan mereka kepada pembolehubah luar, yang kadang-kadang tidak apa yang anda mahu:
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 dalam baris (1) adalah sentiasa nilai semasa i, bukan nilai yang ada ketika fungsi dicipta. Selepas gelung selesai, i mempunyai nilai 5, itulah sebabnya semua fungsi dalam array mengembalikan nilai itu. Jika anda mahu fungsi dalam baris (1) untuk menerima snapshot nilai semasa i, anda boleh menggunakan IIFE:
for (var i=0; i < 5; i++) {
(function () {
var i2 = i; // copy current i
result.push(function () { return i2 });
}());
}
Bahagian ini merangkumi dua mekanisme berorientasikan objek asas JavaScript: objek tunggal dan pembina (yang merupakan kilang untuk objek, serupa dengan kelas dalam bahasa lain).
Seperti semua nilai, objek mempunyai sifat. anda boleh, sebenarnya, menganggap objek sebagai satu set sifat, di mana setiap sifat adalah pasangan (kunci, nilai). kunci adalah rentetan, dan nilai adalah mana-mana nilai JavaScript.
Dalam JavaScript, anda boleh membuat objek biasa secara langsung, melalui literal objek:
'use strict';
var jane = {
name: 'Jane',
describe: function () {
return 'Person named '+this.name;
}
};
Objek sebelumnya mempunyai sifat nama dan menerangkan. Anda boleh membaca (
> jane.name // get
'Jane'
> jane.name = 'John'; // set
> jane.newProperty = 'abc'; // property created automatically
Ciri-ciri bernilai fungsi seperti describe dipanggil kaedah. Mereka menggunakan ini untuk merujuk kepada objek yang digunakan untuk memanggilnya:
> jane.describe() // call method
'Person named John'
> jane.name = 'Jane';
> jane.describe()
'Person named Jane'
Operator dalam memeriksa sama ada harta wujud:
> 'newProperty' in jane
true
> 'foo' in jane
false
Jika anda membaca sifat yang tidak wujud, anda mendapat nilai undefined. Oleh itu dua pemeriksaan sebelumnya juga boleh dilakukan seperti ini:
> jane.newProperty !== undefined
true
> jane.foo !== undefined
false
Operator delete memadamkan sifat:
> delete jane.newProperty
true
> 'newProperty' in jane
false
Kunci sifat boleh menjadi mana-mana rentetan. Setakat ini, kita telah melihat kunci sifat dalam literal objek dan selepas pengendali titik. Walau bagaimanapun, anda hanya boleh menggunakannya dengan cara itu jika mereka adalah pengenal (lihat pengenal dan nama pembolehubah). Jika anda ingin menggunakan rentetan lain sebagai kunci, anda perlu mengutip mereka dalam literal objek dan menggunakan kurungan persegi untuk mendapatkan dan menetapkan sifat:
> var obj = { 'not an identifier': 123 };
> obj['not an identifier']
123
> obj['not an identifier'] = 456;
Perangkai persegi juga membolehkan anda mengira kunci harta:
> var obj = { hello: 'world' };
> var x = 'hello';
> obj[x]
'world'
> obj['hel'+'lo']
'world'
Jika anda mengekstrak kaedah, ia kehilangan hubungannya dengan objek. dengan sendirinya, fungsi itu bukan lagi kaedah, dan ini mempunyai nilai tidak ditakrifkan (dalam mod ketat).
Sebagai contoh, mari kita kembali ke objek Jane sebelumnya:
'use strict';
var jane = {
name: 'Jane',
describe: function () {
return 'Person named '+this.name;
}
};
Kami ingin mengekstrak kaedah describe dari jane, meletakkannya ke dalam pembolehubah fungsi, dan memanggilnya.
> var func = jane.describe;
> func()
TypeError: Cannot read property 'name' of undefined
Penyelesaian adalah menggunakan kaedah bind() yang dimiliki semua fungsi. Ia mewujudkan fungsi baru yang selalu mempunyai nilai yang diberikan:
> var func2 = jane.describe.bind(jane);
> func2()
'Person named Jane'
Setiap fungsi mempunyai pembolehubah khas sendiri ini. Ini tidak selesa jika anda menyarang fungsi di dalam kaedah, kerana anda tidak boleh mengakses kaedah ini dari fungsi. Berikut adalah contoh di mana kita memanggil forEach dengan fungsi untuk berulang 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);
});
}
}
Panggilan logHiToFriends menghasilkan ralat:
> jane.logHiToFriends()
TypeError: Cannot read property 'name' of undefined
Mari kita lihat dua cara untuk memperbaiki ini. pertama, kita boleh menyimpan ini dalam pembolehubah yang berbeza:
logHiToFriends: function () {
'use strict';
var that = this;
this.friends.forEach(function (friend) {
console.log(that.name+' says hi to '+friend);
});
}
Atau, forEach mempunyai parameter kedua yang membolehkan anda memberikan nilai untuk ini:
logHiToFriends: function () {
'use strict';
this.friends.forEach(function (friend) {
console.log(this.name+' says hi to '+friend);
}, this);
}
Ungkapan fungsi sering digunakan sebagai argumen dalam panggilan fungsi dalam JavaScript. Sentiasa berhati-hati apabila anda merujuk ini dari salah satu ungkapan fungsi tersebut.
Hingga kini, anda mungkin berfikir bahawa objek JavaScript hanya peta dari rentetan kepada nilai, sebuah konsep yang dicadangkan oleh literal objek JavaScript
Sebagai tambahan kepada fungsi dan kaedah
// 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 bahawa pembina mempunyai dua bahagian. Pertama, fungsi Point menetapkan data contoh. Kedua, sifat Point.prototype mengandungi objek dengan kaedah. Data yang pertama adalah khusus untuk setiap contoh, sementara data terakhir dikongsi di antara semua contoh.
Untuk menggunakan Point, kita memanggilnya melalui operator baru:
> var p = new Point(3, 5);
> p.x
3
> p.dist()
5.830951894845301
p adalah satu contoh Point:
> p instanceof Point
true
Array adalah urutan elemen yang boleh diakses melalui indeks bilangan bulat bermula dari sifar.
Array literals berguna untuk mencipta array:
> var arr = [ 'a', 'b', 'c' ];
Array sebelumnya mempunyai tiga elemen: rentetan
> arr[0]
'a'
> arr[0] = 'x';
> arr
[ 'x', 'b', 'c' ]
Sifat panjang menunjukkan berapa banyak elemen array mempunyai. Anda boleh menggunakannya untuk menambah unsur dan untuk membuang unsur:
> var arr = ['a', 'b'];
> arr.length
2
> arr[arr.length] = 'c';
> arr
[ 'a', 'b', 'c' ]
> arr.length
3
> arr.length = 1;
> arr
[ 'a' ]
Operator dalam berfungsi 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 bahawa array adalah objek dan dengan itu boleh mempunyai sifat objek:
> var arr = [];
> arr.foo = 123;
> arr.foo
123
Array mempunyai banyak kaedah (lihat Array Prototype Methods). Berikut 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'
Terdapat beberapa kaedah array untuk mengulangi elemen (lihat Iterasi (Tidak merosakkan)). Dua yang paling penting adalah forEach dan peta.
forEach mengulangi array dan menyerahkan elemen semasa dan indeksnya kepada fungsi:
[ 'a', 'b', 'c' ].forEach(
function (elem, index) { // (1)
console.log(index + '. ' + elem);
});
Kod sebelumnya menghasilkan output berikut:
0. a
1. b
2. c
Perhatikan bahawa fungsi dalam baris (1) bebas mengabaikan argumen. Ia boleh, sebagai contoh, hanya mempunyai parameter elem.
peta mencipta array baru dengan menggunakan fungsi untuk setiap elemen array yang sedia ada:
> [1,2,3].map(function (x) { return x*x })
[ 1, 4, 9 ]
JavaScript mempunyai sokongan terbina dalam untuk ungkapan biasa.
/^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 mengandungi pencocokan lengkap pada indeks 0, tangkapan kumpulan pertama pada indeks 1, dan sebagainya. Terdapat cara (dibahas dalam RegExp.prototype.exec: Capture Groups) untuk memanggil kaedah ini berulang kali untuk mendapatkan semua perlawanan.
> '<a> <bbb>'.replace(/<(.*?)>/g, '[$1]')
'[a] [bbb]'
Parameter pertama penggantian mestilah ungkapan biasa dengan bendera /g; jika tidak, hanya kejadian pertama yang diganti.
Matematik 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