Penjelasan terperinci tentang fungsi JavaScript_Pengetahuan asas

WBOY
Lepaskan: 2016-05-16 16:31:14
asal
1250 orang telah melayarinya

Pengenalan

Dalam banyak bahasa tradisional (C/C/Java/C#, dll.), fungsi wujud sebagai warga kelas kedua Anda hanya boleh mengisytiharkan fungsi menggunakan kata kunci bahasa dan kemudian memanggilnya fungsi sebagai parameter Menyalurkannya ke fungsi lain, memberikannya kepada pembolehubah setempat, atau menggunakannya sebagai nilai pulangan memerlukan kaedah khas seperti penunjuk fungsi dan perwakilan.
Dalam dunia JavaScript, fungsi adalah warga kelas pertama Mereka bukan sahaja mempunyai semua cara menggunakan fungsi tradisional (pengisytiharan dan panggilan), tetapi juga boleh menetapkan nilai, lulus parameter, dan mengembalikan seperti nilai mudah -fungsi kelas pertama. Bukan itu sahaja, fungsi dalam JavaScript juga bertindak sebagai pembina kelas dan merupakan contoh kelas Fungsi. Pelbagai identiti sedemikian menjadikan fungsi JavaScript sangat penting.

1. Fungsi JavaScript peringkat permulaan

Seperti bahasa lain, fungsi JavaScript mengikut prinsip pengisytiharan dahulu dan digunakan kemudian Nama fungsi hanya boleh mengandungi huruf, nombor, garis bawah atau $ dan tidak boleh bermula dengan nombor. Terdapat dua cara biasa untuk mengisytiharkan fungsi:

Salin kod Kod adalah seperti berikut:

// Terus mengisytiharkan fungsi myfunc
function myfunc(/* argumen */) {
}

//Tetapkan fungsi tanpa nama kepada pembolehubah tempatan myfunc
var myfunc = function(/* argumen */) {
}

Perhatikan bahawa terdapat perbezaan yang ketara antara dua kaedah pengisytiharan fungsi di atas: kaedah pertama ialah fungsi yang dinamakan apabila diisytiharkan, sama ada ia diisytiharkan sebelum panggilan, selepas panggilan, atau bahkan dalam kedudukan yang tidak akan dilaksanakan (seperti penyataan pulangan atau dalam cawangan yang tidak akan pernah benar), boleh diakses dalam keseluruhan skop cara kedua ialah dengan memberikan fungsi tanpa nama kepada pembolehubah, yang bukan sahaja pengisytiharan fungsi (pengisytiharan fungsi ) ialah fungsi; ekspresi. Fungsi ini tidak boleh diakses oleh mana-mana kod sebelum tugasan, yang bermaksud bahawa tugasan mesti diselesaikan sebelum memanggil, jika tidak, ralat akan berlaku semasa memanggil: "TypeError: undefined is not a function ". Contohnya:

Salin kod Kod adalah seperti berikut:

myfunc1(); // Boleh dipanggil secara normal kerana myfunc1 diisytiharkan terus

fungsi myfunc1() {
}

myfunc2(); // Ralat TypeError: undefined bukan fungsi

var myfunc2 = function() {
};


Kaedah asas untuk memanggil fungsi adalah sama seperti dalam bahasa tradisional menggunakan sepasang kurungan: myfunc(). Fungsi JavaScript juga menyokong panggilan rekursif langsung atau tidak langsung Contohnya, fungsi Fibonacci klasik boleh dilaksanakan dalam JavaScript seperti ini:

Salin kod Kod adalah seperti berikut:

fungsi fib(n) {
Jika (n == 1 || n == 2) {
Kembalikan 1; } lain {
Kembalikan fib(n - 2) fib(n - 1); }
}


Fungsi dalam JavaScript boleh mengendalikan parameter panjang boleh ubah Di dalam fungsi, terdapat pembolehubah tempatan bernama argumen, yang merupakan objek seperti tatasusunan yang mengandungi semua parameter yang dihantar apabila dipanggil . Contohnya:

ujian fungsi() {
alert(arguments.length); }

ujian(1); // 1
ujian(1, 'a'); // 2
test(true, [], {}); // 3 Argumen boleh digunakan untuk melaksanakan fungsi yang serupa dengan bahasa C printf, dan juga boleh digunakan untuk melaksanakan polimorfisme kaedah.

2. Fungsi JavaScript lanjutan

2.1 Fungsi tanpa nama dan fungsi bersarang

Dalam JavaScript, anda boleh mengisytiharkan fungsi tanpa nama, dipanggil fungsi tanpa nama. Pada masa yang sama, JavaScript juga membenarkan fungsi diisytiharkan dalam fungsi, dipanggil fungsi bersarang Skop fungsi bersarang ialah keseluruhan fungsi induk.

Dalam bahagian pengisytiharan fungsi sebelumnya, kami melihat penggunaan fungsi tanpa nama dan fungsi bersarang Oleh kerana fungsi tanpa nama tidak mempunyai nama, ia tidak akan memperkenalkan pembolehubah baharu untuk mencemarkan konteks, dan akan membawa skop pembolehubah baharu digunakan untuk mencegah pencemaran alam sekitar global.

Terdapat persekitaran global khas (objek global) dalam masa jalan JavaScript Objek ini menyimpan fungsi dan pembolehubah global Dalam pembangunan sebenar, beberapa perpustakaan pihak ketiga atau berbilang fail js sering digunakan atau pengisytiharan fungsi akan menyebabkan kekeliruan dalam pelaksanaan kod. Sebagai contoh, dua fail js diperkenalkan satu demi satu, dan masing-masing mentakrifkan log fungsinya sendiri untuk kegunaan dalaman Fungsi kedua yang diperkenalkan akan menimpa definisi pertama dan tidak akan menyebabkan sebarang ralat memanggil fungsi log dalam pelaksanaan berikutnya. menyebabkan kesilapan. Pada masa ini, menggunakan fungsi tanpa nama untuk membungkus logik dalam keseluruhan js boleh mengelakkan ralat ini. Kaedah ini telah digunakan oleh kebanyakan perpustakaan js sumber terbuka.

Salin kod Kod adalah seperti berikut:

(function() { // Fungsi tanpa nama

log fungsi(msg) {
console.log(msg);
}

// Kod lain

}()); // Laksanakan segera

Kod di atas ialah contoh mudah Skop fungsi log terhad kepada fungsi tanpa nama ini, dan fungsi tanpa nama dikelilingi oleh sepasang kurungan () di luar untuk membentuk ungkapan fungsi fungsi, diikuti dengan sepasang kurungan untuk menunjukkan bahawa fungsi itu akan dilaksanakan serta-merta, membenarkan kod asal dilaksanakan secara normal. Walau bagaimanapun, fungsi yang diisytiharkan dengan cara ini, pembolehubah yang diisytiharkan melalui var, dsb. adalah dalaman dan tidak boleh diakses oleh mana-mana kod selain daripada fungsi tanpa nama. Jika anda perlu mendedahkan beberapa fungsi sebagai antara muka, terdapat beberapa kaedah:

Salin kod Kod adalah seperti berikut:

var mylib = (fungsi(global) {

log fungsi(msg) {
console.log(msg);
}

log1 = log; // Kaedah 1: Gunakan kelakuan lalai pengisytiharan pembolehubah tanpa var dan jadikan log1 pembolehubah global (tidak disyorkan)

global.log2 = log; // Kaedah 2: Tambahkan atribut log2 terus ke objek global dan tetapkan nilai kepada fungsi log (disyorkan)

return { // Kaedah 3: Dapatkan satu siri objek pengumpulan fungsi antara muka melalui nilai pulangan fungsi tanpa nama, dan tetapkan mereka kepada pembolehubah global mylib (disyorkan)
Log: log
};

}(tingkap));

2.2 Fungsi Tertib Tinggi

Jika fungsi digunakan sebagai parameter atau nilai pulangan, ia dipanggil fungsi tertib tinggi Semua fungsi dalam JavaScript boleh digunakan sebagai fungsi tertib tinggi Ini juga merupakan ciri jenis fungsi pertama. Di bawah ini kami akan menganalisis kedua-dua kaedah penggunaan ini masing-masing.

Salin kod Kod adalah seperti berikut:

fungsi negatif(n) {
Kembalikan -n; // Ambil nilai bertentangan dengan n
}

fungsi segi empat sama(n) {
Kembalikan n*n; // n kuasa dua
}

proses fungsi(nombor, panggil balik) {
var hasil = [];
for(var i = 0, length = nums.length; i < length; i ) {
result[i] = callback(nums[i]); // Hantar semua elemen dalam array nums ke panggil balik untuk diproses, dan simpan nilai pulangan sebagai hasilnya
}

Pulangan hasil; }

var nums = [-3, -2, -1, 0, 1, 2, 3, 4]; var n_neg = proses(bilangan, negatif); // n_neg = [3, 2, 1, 0, -1, -2, -3, -4]; var n_square = proses(bilangan, persegi); // n_square = [9, 4, 1, 0, 1, 4, 9, 16];

Kod di atas menunjukkan contoh menghantar fungsi sebagai parameter ke dalam panggilan proses fungsi yang lain Dalam pelaksanaan fungsi proses, panggilan balik dianggap sebagai kotak hitam, bertanggungjawab untuk menghantar parameter kepadanya, dan kemudian mendapatkannya. nilai pulangan Pelaksanaan khusus panggilan balik tidak jelas sebelum ini. Hanya apabila baris 20 dan 22 dilaksanakan, panggil balik masing-masing diwakili oleh negatif atau segi empat sama, dan operasi nilai bertentangan atau kuasa dua dilakukan pada setiap elemen masing-masing.

Salin kod Kod adalah seperti berikut:

penjana fungsi() {
var i = 0; Kembalikan fungsi() {
Kembalikan i ; };
}

var gen1 = generator(); // Dapatkan penjana nombor asli
var gen2 = generator(); // Dapatkan penjana nombor semula jadi
var r1 = gen1(); // r1 = 0
var r2 = gen1(); // r2 = 1
var r3 = gen2(); // r3 = 0
var r4 = gen2(); // r4 = 1


Kod di atas menunjukkan contoh penggunaan fungsi sebagai penjana nilai semula ialah fungsi penjana nombor asli, dan nilai pulangan ialah fungsi penjana nombor asli. Setiap kali penjana dipanggil, fungsi tanpa nama dikembalikan sebagai hasilnya Fungsi tanpa nama ini mengembalikan setiap nombor semula jadi apabila ia sebenarnya dipanggil. Pembolehubah i dalam penjana akan meningkat sebanyak 1 setiap kali fungsi tanpa nama ini dipanggil. Ini sebenarnya adalah penutupan. Mari perkenalkan penutupan di bawah.



2.3 Penutupan
Penutupan (Penutupan) bukanlah konsep baharu yang digunakan dalam banyak bahasa berfungsi. Dalam JavaScript, penutupan digunakan apabila anda menggunakan pembolehubah dalam skop fungsi luaran dalam fungsi sebaris. Gunakan analogi biasa untuk menerangkan hubungan antara penutupan dan kelas: kelas ialah data dengan fungsi, dan penutupan ialah fungsi dengan data. Satu ciri pembolehubah yang digunakan dalam penutupan ialah ia tidak dikeluarkan apabila fungsi induk kembali, tetapi berakhir apabila kitaran hayat penutupan tamat. Sebagai contoh, seperti contoh penjana dalam bahagian sebelumnya, gen1 dan gen2 menggunakan pembolehubah bebas i (apabila i gen1 meningkat sebanyak 1, i gen2 tidak terjejas, dan sebaliknya), selagi gen1 atau gen2 Jika kedua-dua pembolehubah bukan sampah yang dikumpul oleh enjin JavaScript, pembolehubah i masing-masing tidak akan dikeluarkan. Dalam pengaturcaraan JavaScript, penutupan digunakan secara tidak sedar Walaupun ciri penutupan ini membawa kemudahan penggunaan, ia juga boleh menyebabkan masalah seperti kebocoran memori. Contohnya:

var elem = document.getElementById('test'); elem.addEventListener('klik', function() {
alert('Anda mengklik ' elem.tagName); });



Fungsi kod ini adalah untuk memaparkan nama label nod apabila ia diklik. Ia mendaftarkan fungsi tanpa nama sebagai fungsi pemprosesan peristiwa klik bagi nod DOM. Elemen objek DOM dirujuk dalam fungsi, membentuk a Beg tertutup. Ini akan menghasilkan rujukan bulat, iaitu: DOM-> Penutupan->DOM-> objek wujud, jadi penutupan tidak akan dikeluarkan sebelum objek DOM dikeluarkan Walaupun objek DOM dipadamkan dalam pepohon DOM, disebabkan kewujudan rujukan bulat ini, objek DOM mahupun penutupan tidak akan dikeluarkan. Anda boleh mengelakkan kebocoran memori ini dengan menggunakan kaedah berikut:

Salin kod

Kod adalah seperti berikut: var elem = document.getElementById('test'); elem.addEventListener('klik', function() { alert('Anda mengklik ' this.tagName); // Tidak lagi merujuk kepada pembolehubah elem secara langsung
});



Dalam kod di atas, ini digunakan dan bukannya elem (dalam fungsi pengendalian acara DOM, penunjuk ini menunjuk kepada elemen DOM itu sendiri), supaya masa jalan JS tidak lagi berfikir bahawa pembolehubah kelas induk digunakan dalam fungsi ini, jadi penutupan tidak lagi terbentuk.
Penutupan juga akan membawa banyak masalah kebocoran memori yang serupa Hanya beri perhatian kepada penutupan semasa menulis kod untuk cuba mengelakkan masalah tersebut.
Pembina Kelas 2.4


Fungsi JavaScript juga berfungsi sebagai pembina kelas, jadi selagi anda mengisytiharkan fungsi, anda boleh menggunakan kata kunci baharu untuk mencipta contoh kelas.


Salin kod

Kod adalah seperti berikut:

fungsi Orang(nama) {
This.name = nama;
This.toString = function() {
Kembalikan 'Helo, ' this.name '!';
};
}

var p = Orang baharu('Ghostheaven'); alert(p); // Hello, Ghostheaven! Dalam contoh di atas, fungsi Person digunakan sebagai pembina kelas Pada masa ini, ini menunjukkan kepada objek contoh yang baru dibuat . Mengenai pengaturcaraan JavaScript berorientasikan objek terperinci Anda boleh merujuk artikel ini. Apa yang saya ingin bincangkan di sini ialah isu nilai pulangan apabila fungsi JavaScript digunakan sebagai pembina kelas.

Salin kod Kod adalah seperti berikut:
fungsi MyClass(nama) {
This.name = nama;
Kembalikan nama; // Kembalikan nilai pembina? }

var obj1 = MyClass('foo');
var obj2 = MyClass('foo'); var obj3 = MyClass({});
var obj4 = MyClass({});



Pembina di atas agak istimewa, ia mempunyai pernyataan pulangan, jadi objek apa yang masing-masing dituju oleh obj1~obj4? Keputusan sebenar adalah ini:

Salin kod Kod adalah seperti berikut: obj1 = objek MyClass
obj2 = 'foo'
obj3 = {}
obj4 = {}



Sebab khusus diterangkan dalam artikel ini, dan saya tidak akan menerangkan butiran dalam artikel ini Memandangkan pembina dengan nilai pulangan akan menghasilkan hasil yang pelik, jangan panggil penyata pulangan dengan nilai pulangan dalam pembina (a. pulangan kosong adalah OK).


3. Tahap raksasa fungsi JavaScript

Selamat datang ke kawasan pengajaran fungsi peringkat raksasa, di mana kami akan mengajar anda cara menghadapi raksasa dengan tenang dan selesa. . .

Kelas fungsi 3.1

Terdapat kelas terbina dalam yang dipanggil Fungsi dalam masa jalan JavaScript. Mengisytiharkan fungsi dengan kata kunci fungsi sebenarnya adalah bentuk ringkas untuk mencipta objek kelas Fungsi Semua fungsi mempunyai semua kaedah kelas Fungsi, seperti panggilan, gunakan, dan ikat. Tunggu, anda boleh mengesahkan kenyataan ini melalui kata kunci instanceof. Oleh kerana Function ialah kelas, pembinanya ialah Function (itu sendiri juga merupakan objek kelas Function), dan ia sepatutnya boleh menjana objek fungsi melalui kata kunci baharu. Inilah raksasa pertama, iaitu cara membina fungsi menggunakan kelas Fungsi. Sintaks Fungsi adalah seperti berikut:

Salin kod Kod adalah seperti berikut: Fungsi baharu ([arg1[, arg2[, ... argN]],] functionBody)


Antaranya, arg1, arg2, ... argN ialah rentetan, mewakili nama parameter, dan functionBody juga merupakan rentetan, mewakili badan fungsi Nama parameter sebelumnya boleh menjadi lebih atau kurang parameter terakhir sebagai Dalam badan fungsi, yang sebelumnya dianggap sebagai parameter.

Salin kod Kod adalah seperti berikut: var func1 = new Function('name', 'return "Hello, " name "!";');
func1('Ghostheaven'); // Hello, Ghostheaven!



Kaedah di atas membina fungsi melalui Fungsi Fungsi ini betul-betul sama dengan fungsi lain yang diisytiharkan dengan kata kunci fungsi.
Melihat perkara ini, mungkin ramai yang bertanya mengapa raksasa seperti itu diperlukan? "Apa sahaja yang wujud adalah munasabah." Kelas Fungsi mempunyai kegunaannya yang unik Anda boleh menggunakannya untuk menjana pelbagai logik fungsi secara dinamik, atau menggantikan fungsi fungsi eval dan mengekalkan persekitaran semasa daripada tercemar*.



3.2 Fungsi kemas kini diri

Dalam banyak bahasa, sebaik sahaja fungsi diisytiharkan, ia tidak boleh mengisytiharkan fungsi dengan nama yang sama sekali lagi, jika tidak ralat sintaks akan berlaku Walau bagaimanapun, fungsi dalam JavaScript bukan sahaja boleh diisytiharkan berulang kali, tetapi juga mengemas kini sendiri. Raksasa yang makan sendiri ada di sini!

Label berkaitan:
sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan