Fungsi hubungi dan terapkan jarang digunakan dalam beberapa operasi JavaScript sederhana. Dalam operasi besar lainnya, seperti pengembangan aplikasi web, kedua fungsi ini dapat sering ditemui dalam pengembangan kerangka kerja JS. Ada juga banyak informasi tentang penjelasan dari dua fungsi ini, tetapi saya pikir banyak informasi yang ditulis atau sangat mirip, dan tidak memiliki penjelasan yang sederhana. Selanjutnya, saya mencoba menganalisis dan menjelaskan dua fungsi ini dengan ide yang lebih jelas dan lebih sederhana.
Salinan kode adalah sebagai berikut:
Kami dapat menganggap panggilan () dan menerapkan () sebagai metode objek tertentu, dan secara tidak langsung memanggil fungsi dengan memanggil metode implementasi. Argumen pertama panggilan () dan apply () adalah objek induk untuk memanggil fungsi. Ini adalah konteks panggilan, dan referensi untuk itu diperoleh melalui ini di badan fungsi. Untuk memanggil fungsi f () pada metode objek O, Anda dapat menggunakan panggilan () dan terapkan () seperti ini: f.call (o) f.Apply (o). [1]
Mari kita analisis panggilan terlebih dahulu. Berikut adalah penjelasan dari fungsi panggilan oleh edisi ke-3 ecmascript [2]: Ketika metode panggilan dipanggil oleh objek fungsi (func.call (0)), parameter yang diperlukan dan beberapa parameter yang tidak penting perlu diteruskan. Proses eksekusi adalah sebagai berikut:
A, jika objek yang menelepon panggilan tidak berjalan, kesalahan TypeError dilemparkan.
b, atur daftar parameter menjadi kosong
C, jika metode yang dipanggil melewati lebih dari satu parameter, maka masukkan arg1, arg2 ... ke dalam daftar parameter pada gilirannya
D, Mengembalikan hasil panggilan panggilan, ganti ini dalam fungsi panggilan (func) dengan parameter 1 yang diteruskan, dan perlakukan daftar parameter yang diteruskan sebagai parameter fungsi ini.
Bahkan, fungsi panggilan adalah prototipe objek fungsi. Dengan kata lain, fungsi yang panggilan harus juga merupakan fungsi. Saat menelepon panggilan ini, cukup ganti ini dalam fungsi yang memanggil panggilan dengan objek yang dilewati. Inilah contohnya:
<script> fungsi c1 () {this.name = 'zhang san'; this.age = '24 '; this.sayname = function () {console.log ("Ini kelas C1, nama saya:"+this.name+"usia saya adalah"+this.age); }} function c2 () {this.name = 'li si'; this.age = '25 '; } var c1 = c1 baru (); var c2 = c2 baru (); c1.sayname (); c1.sayname.call (c2); </script>Hasil Eksekusi:
Ini kategori C1, nama saya: Zhang San Usia saya berusia 24 tahun
Ini kategori C1, nama saya: li si usianya 25 tahun
Dalam kode di atas, dua kelas dinyatakan, C1 dan C2. C1 memiliki dua properti, satu metode, dan C2 juga memiliki dua properti yang sama dengan C1. Setelah instantiasi, c1.sayname () mencetak properti aktual, tetapi c1.sayname.call (C2) mencetak properti C2, mengapa ini? Karena SayName () adalah fungsi dan ada ini di badan fungsi, ketika panggilan dieksekusi, ini akan digantikan oleh C2, sehingga atribut C2 pada akhirnya akan dicetak.
Perbedaan antara Apply dan Call terletak pada lewat parameter opsional. Semua parameter opsional dari Apply disimpan dalam array, karena satu parameter dimasukkan, sementara panggilan diteruskan ke beberapa parameter.
Jadi, apa aplikasi fungsi Apply and Call? Yang pertama adalah menemukan elemen terbesar dalam array numerik di jaringan. Anda dapat menggunakan Math.max.Apply (null, array) secara langsung. Yang lainnya adalah menggunakan Apply dan Call untuk mewarisi, sebagai berikut:
<script> function Human (name, sex) {this.name = name; this.sex = seks; this.walk = function () {console.log ('I'm Walking'); }} function child () {human.call (this, "xiao ming", "Male") this.paly = function () {console.log ('Saya suka bermain sangat banyak'); } this.intruduce = function () {console.log ('Halo semuanya, i'+this.name); }} var jinp = manusia baru ('jack', 'laki -laki'); var xiaoping = anak baru (); xiaoping.walk (); xiaoping.paly (); xiaoping.intruduce (); </script>Hasil Eksekusi:
Saya berjalan
Saya sangat suka bermain
Halo semuanya, saya xiao ming
Fungsi yang serupa dengan call () dan apply () adalah bind (), yang merupakan metode baru yang ditambahkan dalam ecmascript 5, tetapi dapat dengan mudah disimulasikan dalam ecmascript 3. Fungsi BIND juga merupakan fungsi. Metode Prototipe dalam JavaScript. Konten utama dari metode ini adalah mengikat fungsi ke suatu objek. Ketika metode bind () terikat pada fungsi f () dan objek O dilewatkan sebagai parameter, metode ini akan mengembalikan fungsi baru dan dipanggil sebagai metode o. Argumen apa pun yang diteruskan ke fungsi baru akan diteruskan ke fungsi asli. sebagai berikut:
<script> function pengantar (negara, hobi) {return "Halo semuanya, nama saya adalah"+this.name+", tahun ini"+this.age+"tahun, dari"+country+", seperti"+hobi; } var xiaoming = {name: "xiao ming", usia: 20} var jieshao = memperkenalkan.bind (xiaoming); Console.log (Jieshao ("Cina", "bermain bola")); </script>Hasil Eksekusi:
Halo semuanya, Nama saya Xiao Ming, saya berumur 20 tahun, dari China, saya suka bermain basket
Contoh di atas setara dengan:
<script> function pengantar (negara, hobi) {return "Halo semuanya, nama saya adalah"+this.name+", tahun ini"+this.age+"tahun, dari"+country+", seperti"+hobi; } var xiaoming = {name: "xiaoming", usia: 20} console.log (perkenalan. Apply (xiaoming, ["cina", "play"])); // atau console.log (perkenalanPerlu dicatat bahwa dalam mode ketat Ecmascript 5, argumen nyata pertama panggilan () dan apply () akan menjadi nilai ini, bahkan jika argumen nyata yang dilewatkan adalah nilai asli atau bahkan nol atau tidak terdefinisi. Dalam mode ecmascript 3 dan non-ketat, nol yang dilewatkan dan tidak ditentukan akan digantikan oleh konfrontasi global, sementara nilai asli lainnya akan digantikan oleh objek pembungkus yang sesuai.
Referensi
[1], Panduan JavaScript otoritatif, edisi ke -6, halaman 189
[2], function.prototype.call (thisarg [, arg1 [, arg2, ...]])
[3], function.prototype.apply (Thisarg, Argarray)