Apa perbedaan antara menggunakan call
dan apply
menjalankan fungsi?
var func = function() {
alert('hello!');
};
func.apply();
vs. func.call();
Apakah ada perbedaan kinerja antara kedua metode yang disebutkan di atas? Kapan sebaiknya menggunakan call
lebih dari apply
dan sebaliknya?
javascript
performance
function
dynamic
John Duff
sumber
sumber
a
di terapkan untuk array argumen danc
panggilan untuk kolom argumen.fn(...input)
mana input adalah array. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…Jawaban:
Perbedaannya adalah bahwa
apply
Anda dapat memanggil fungsi denganarguments
sebagai array;call
membutuhkan parameter yang terdaftar secara eksplisit. Sebuah mnemonic yang berguna adalah " A untuk sebuah RRay dan C untuk c Omma."Lihat dokumentasi MDN tentang mendaftar dan menelepon .
Sintaks semu:
theFunction.apply(valueForThis, arrayOfArgs)
theFunction.call(valueForThis, arg1, arg2, ...)
Ada juga, pada ES6, kemungkinan
spread
array untuk digunakan dengancall
fungsi, Anda dapat melihat kompatibilitas di sini .Kode sampel:
sumber
[]
disebut array ,{}
disebut objek .Array.prototype.slice.call(arguments)
atau[].slice.call(arguments)
. berlaku masuk akal jika Anda memiliki argumen dalam array, misalnya dalam suatu fungsi yang memanggil fungsi lain dengan (hampir) parameter yang sama. Rekomendasi Gunakan panggilan fungsi normalfuncname(arg1)
jika melakukan apa yang Anda butuhkan, dan simpan panggilan dan ajukan untuk acara-acara khusus ketika Anda benar-benar membutuhkannya.call
danapply
mengambil dua parameter. Argumenapply' and
fungsi call` pertama harus menjadi objek pemilik dan parameter kedua akan menjadi parameter array atau dipisahkan koma masing-masing. Jika Anda lulusnull
atauundefined
sebagai argumen pertama maka dalam mode non-ketat mereka diganti dengan objek global yaituwindow
K. Scott Allen memiliki artikel bagus tentang masalah ini.
Pada dasarnya, mereka berbeda pada bagaimana mereka menangani argumen fungsi.
Begitu:
sumber
call
tetapi persyaratan untukapply
Untuk menjawab bagian tentang kapan harus menggunakan setiap fungsi, gunakan
apply
jika Anda tidak tahu jumlah argumen yang akan Anda lewati, atau jika sudah ada dalam array atau objek mirip array (sepertiarguments
objek untuk meneruskan argumen Anda sendiri. Gunakancall
sebaliknya, karena tidak perlu membungkus argumen dalam array.Ketika saya tidak memberikan argumen apa pun (seperti contoh Anda), saya lebih suka
call
karena saya memanggil fungsi.apply
akan menyiratkan Anda menerapkan fungsi ke argumen (tidak ada).Seharusnya tidak ada perbedaan kinerja, kecuali mungkin jika Anda menggunakan
apply
dan membungkus argumen dalam sebuah array (misalnyaf.apply(thisObject, [a, b, c])
bukanf.call(thisObject, a, b, c)
). Saya belum mengujinya, jadi mungkin ada perbedaan, tetapi akan sangat spesifik browser. Kemungkinancall
lebih cepat jika Anda belum memiliki argumen dalam array danapply
lebih cepat jika Anda melakukannya.sumber
Ini mnemonik yang bagus. Seorang ply menggunakan A rrays dan A lways membutuhkan satu atau dua argumen. Ketika Anda menggunakan C semua yang Anda miliki untuk C jumlah argumen.
sumber
apply
diperlukan parameter pertama atau kedua . Saya tidak yakin mengapa seseorang akan memanggilapply
ataucall
tanpa parameter. Sepertinya seseorang sedang mencari tahu mengapa di sini stackoverflow.com/questions/15903782/…Meskipun ini adalah topik lama, saya hanya ingin menunjukkan bahwa .call sedikit lebih cepat daripada .apply. Saya tidak bisa memberi tahu Anda mengapa.
Lihat jsPerf, http://jsperf.com/test-call-vs-apply/3
[
UPDATE!
]Douglas Crockford menyebutkan secara singkat perbedaan antara keduanya, yang dapat membantu menjelaskan perbedaan kinerja ... http://youtu.be/ya4UHuXNygM?t=15m52s
Berlaku mengambil array argumen, sementara Panggilan mengambil nol atau lebih parameter individual! Ah hah!
.apply(this, [...])
.call(this, param1, param2, param3, param4...)
sumber
Mengikuti ekstrak dari Penutupan: Panduan Definitif oleh Michael Bolin . Ini mungkin terlihat agak panjang, tetapi penuh dengan banyak wawasan. Dari "Lampiran B. Konsep JavaScript yang Sering Disalahpahami":
Apa yang
this
Merujuk Ketika Suatu Fungsi DipanggilSaat memanggil fungsi formulir
foo.bar.baz()
, objekfoo.bar
disebut sebagai penerima. Ketika fungsi dipanggil, itu adalah penerima yang digunakan sebagai nilai untukthis
:Jika tidak ada penerima eksplisit ketika suatu fungsi dipanggil, maka objek global menjadi penerima. Seperti yang dijelaskan dalam "goog.global" di halaman 47, jendela adalah objek global ketika JavaScript dieksekusi di browser web. Ini mengarah pada beberapa perilaku mengejutkan:
Meskipun
obj.addValues
danf
merujuk ke fungsi yang sama, mereka berperilaku berbeda ketika dipanggil karena nilai penerima berbeda di setiap panggilan. Untuk alasan ini, saat memanggil fungsi yang merujukthis
, penting untuk memastikan bahwathis
akan memiliki nilai yang benar ketika dipanggil. Agar jelas, jikathis
tidak dirujuk dalam fungsi tubuh, maka perilakuf(20)
danobj.addValues(20)
akan sama.Karena fungsi adalah objek kelas satu dalam JavaScript, mereka dapat memiliki metode mereka sendiri. Semua fungsi memiliki metode
call()
danapply()
yang memungkinkan untuk mendefinisikan ulang penerima (yaitu objek yangthis
merujuk) ketika memanggil fungsi. Tanda tangan metode adalah sebagai berikut:Perhatikan bahwa satu-satunya perbedaan antara
call()
danapply()
yangcall()
menerima parameter fungsi sebagai argumen individual, sedangkanapply()
menerimanya sebagai array tunggal:Panggilan berikut ini setara, seperti
f
danobj.addValues
merujuk ke fungsi yang sama:Namun, karena keduanya
call()
tidakapply()
menggunakan nilai penerimanya sendiri untuk menggantikan argumen penerima ketika tidak ditentukan, hal berikut ini tidak akan berfungsi:Nilai
this
tidak pernah bisanull
atauundefined
ketika suatu fungsi dipanggil. Ketikanull
atauundefined
diberikan sebagai penerima kecall()
atauapply()
, objek global digunakan sebagai nilai untuk penerima sebagai gantinya. Oleh karena itu, kode sebelumnya memiliki efek samping yang tidak diinginkan yang sama dengan menambahkan properti yang dinamaivalue
ke objek global.Mungkin bermanfaat untuk menganggap suatu fungsi sebagai tidak memiliki pengetahuan tentang variabel yang ditugaskan padanya. Ini membantu memperkuat gagasan bahwa nilai ini akan terikat ketika fungsi dipanggil daripada ketika itu didefinisikan.
Akhir ekstrak.
sumber
additionalValues
tidak dirujuk di dalamobj.addValues
tubuhvar f = obj.addValues;
menjadivar f = obj.addValues.bind(obj)
dan sekarang f (20) akan berfungsi tanpa harus menggunakan panggilan atau mendaftar setiap saat.Terkadang berguna untuk satu objek untuk meminjam fungsi dari objek lain, yang berarti bahwa objek pinjaman hanya menjalankan fungsi yang dipinjamkan seolah-olah itu adalah miliknya sendiri.
Contoh kode kecil:
Metode ini sangat berguna untuk memberikan fungsi sementara objek.
sumber
console.log
lihat: Apa itu console.log dan bagaimana cara menggunakannya?Contoh lain dengan Call, Apply dan Bind. Perbedaan antara Panggilan dan Terapkan jelas, tetapi Bind bekerja seperti ini:
}
sumber
Saya ingin menunjukkan contoh, di mana argumen 'valueForThis' digunakan:
Rincian **: http://es5.github.io/#x15.4.4.7 *
sumber
Panggilan () mengambil argumen yang dipisahkan koma, mis:
.call(scope, arg1, arg2, arg3)
dan apply () mengambil array argumen, mis:
.apply(scope, [arg1, arg2, arg3])
berikut ini beberapa contoh penggunaan lainnya: http://blog.i-evaluation.com/2012/08/15/javascript-call-and-apply/
sumber
Dari dokumen MDN pada Function.prototype.apply () :
Dari dokumen MDN pada Function.prototype.call () :
Dari Function.apply dan Function.call dalam JavaScript :
Contoh kode:
Lihat juga Fiddle ini .
sumber
Perbedaan mendasar adalah yang
call()
menerima daftar argumen , sementaraapply()
menerima satu array argumen .sumber
Ini tulisan kecil, saya menulis tentang ini:
http://sizeableidea.com/call-versus-apply-javascript/
sumber
Perbedaannya adalah bahwa
call()
mengambil argumen fungsi secara terpisah, danapply()
mengambil argumen fungsi dalam array.sumber
Kami dapat membedakan metode panggilan dan menerapkan seperti di bawah ini
PANGGILAN: Fungsi dengan argumen yang disediakan secara individual. Jika Anda tahu argumen yang harus diteruskan atau tidak ada argumen untuk lulus, Anda dapat menggunakan panggilan.
BERLAKU: Memanggil fungsi dengan argumen yang disediakan sebagai array. Anda dapat menggunakan berlaku jika Anda tidak tahu berapa banyak argumen yang akan diteruskan ke fungsi.
Ada keuntungan menggunakan apply over call, kita tidak perlu mengubah jumlah argumen hanya kita bisa mengubah array yang diteruskan.
Tidak ada perbedaan besar dalam kinerja. Tetapi kita dapat mengatakan panggilan sedikit lebih cepat dibandingkan dengan menerapkan karena array perlu mengevaluasi dalam menerapkan metode.
sumber
Perbedaan antara metode ini adalah, bagaimana Anda ingin melewatkan parameter.
"A untuk array dan C untuk koma" adalah mnemonic yang praktis.
sumber
Panggilan dan terapkan keduanya digunakan untuk memaksa
this
nilai ketika suatu fungsi dieksekusi. Satu-satunya perbedaan adalah bahwacall
mengambiln+1
argumen di mana 1 beradathis
dan'n' arguments
.apply
hanya membutuhkan dua argumen, satuthis
adalah argumen lainnya.Keuntungan yang saya lihat di
apply
atascall
adalah bahwa kita dapat dengan mudah mendelegasikan pemanggilan fungsi ke fungsi lain tanpa banyak usaha;Amati betapa mudahnya kita didelegasikan
hello
untuksayHello
menggunakanapply
, tetapi dengancall
ini sangat sulit untuk dicapai.sumber
Meskipun
call
danapply
mencapai hal yang sama, saya pikir ada setidaknya satu tempat di mana Anda tidak dapat menggunakancall
tetapi hanya dapat digunakanapply
. Saat itulah Anda ingin mendukung warisan dan ingin memanggil konstruktor.Berikut adalah fungsi yang memungkinkan Anda untuk membuat kelas yang juga mendukung pembuatan kelas dengan memperluas kelas lainnya.
sumber
Ringkasan:
Keduanya
call()
danapply()
merupakan metode yang terletak diFunction.prototype
. Oleh karena itu mereka tersedia pada setiap objek fungsi melalui rantai prototipe. Keduanyacall()
danapply()
dapat menjalankan fungsi dengan nilai yang ditentukan darithis
.Perbedaan utama antara
call()
danapply()
adalah cara Anda harus menyampaikan argumen ke dalamnya. Dalam keduanyacall()
danapply()
Anda lulus sebagai argumen pertama objek yang Anda inginkan nilainyathis
. Argumen lain berbeda dengan cara berikut:call()
Anda harus memasukkan argumen secara normal (mulai dari argumen kedua)apply()
Anda harus melewati berbagai argumen.Contoh:
Mengapa saya harus menggunakan fungsi-fungsi ini?
The
this
nilai dapat kadang-kadang rumit dalam javascript. Nilaithis
ditentukan ketika suatu fungsi dieksekusi bukan ketika suatu fungsi didefinisikan. Jika fungsi kita bergantung padathis
pengikatan hak kita dapat menggunakancall()
danapply()
untuk menegakkan perilaku ini. Sebagai contoh:sumber
Perbedaan utamanya adalah, menggunakan panggilan, kita dapat mengubah ruang lingkup dan meneruskan argumen seperti biasa, tetapi berlaku memungkinkan Anda menyebutnya menggunakan argumen sebagai Array (meneruskannya sebagai array). Tetapi dalam hal apa yang harus mereka lakukan dalam kode Anda, mereka sangat mirip.
Jadi seperti yang Anda lihat, tidak ada perbedaan besar, tapi tetap saja, ada beberapa kasus yang kami lebih suka menggunakan panggilan () atau menerapkan (). Misalnya, lihat kode di bawah ini, yang menemukan angka terkecil dan terbesar dalam array dari MDN, menggunakan metode yang berlaku:
Jadi perbedaan utama adalah cara kita menyampaikan argumen:
Panggil:
Menerapkan:
sumber
Biarkan saya menambahkan sedikit detail untuk ini.
dua panggilan ini hampir setara:
Hanya ada perbedaan kecil:
Jadi, panggilan ini saling melengkapi. Di mana kita mengharapkan iterable ,
call
berfungsi, di mana kita mengharapkan seperti array ,apply
berfungsi.Dan untuk objek yang bisa diubah - ubah dan mirip-array , seperti array nyata, kami secara teknis bisa menggunakan salah satunya, tetapi menerapkan mungkin akan lebih cepat karena sebagian besar mesin JavaScript mengoptimalkannya dengan lebih baik.
sumber