Terapkan, hubungi
Dalam JavaScript, hubungi dan terapkan ada untuk mengubah konteks (konteks) fungsi saat berjalan. Dengan kata lain, itu adalah mengubah arah ini di dalam tubuh fungsi.
Fitur utama JavaScript adalah bahwa fungsi memiliki konsep "konteks definisi" dan "konteks runtime" dan "konteks dapat diubah".
Pertama -tama mari kita dapatkan berangan:
function fruits () {} fruits.prototype = {color: "red", katakan: function () {console.log ("Warna saya adalah" + this.color);}} var apple = buah baru; apple.say (); // Warna saya merahTetapi jika kita memiliki objek pisang = {warna: "kuning"}, dan kita tidak ingin mendefinisikan kembali metode katakan untuk itu, maka kita dapat menggunakan metode ucap apple dengan panggilan atau terapkan:
pisang = {warna: "kuning"} apple.say.call (pisang); // warnanya adalah yellowapple.say.Apply (pisang); // Warna saya berwarna kuningOleh karena itu, dapat dilihat bahwa panggilan dan berlaku tampaknya mengubah ini secara dinamis. Ketika suatu objek tidak memiliki metode tertentu (pisang tidak mengatakan metode dalam kastanye ini), tetapi yang lain (Apple memiliki metode katakan dalam kastanye ini), kita dapat menggunakan panggilan atau berlaku untuk mengoperasikannya dengan metode objek lainnya.
Perbedaan antara Apply dan Call
Untuk Apply dan Call, fungsinya persis sama, tetapi metode menerima parameter berbeda. Misalnya, ada fungsi yang didefinisikan sebagai berikut:
var func = function (arg1, arg2) {};Anda dapat menyebutnya dengan cara berikut:
func.call (ini, arg1, arg2); func.Apply (ini, [arg1, arg2])
Di mana ini adalah konteks yang ingin Anda tentukan, itu bisa menjadi objek JavaScript (semua yang ada di JavaScript adalah objek), panggilan perlu meneruskan parameter secara berurutan, dan menerapkan cara untuk menempatkan parameter di array.
Dalam JavaScript, jumlah parameter suatu fungsi tidak diperbaiki, jadi jika Anda ingin mengatakan kondisi yang berlaku, gunakan panggilan ketika parameter Anda diketahui dengan jelas.
Ketika Anda tidak yakin, gunakan Apply, lalu dorong parameter ke dalam array dan lewati. Ketika jumlah parameter tidak pasti, semua parameter juga dapat dilalui melalui array semu argumen di dalam fungsi.
Untuk mengkonsolidasikan dan memperdalam memori, berikut ini adalah beberapa kegunaan umum:
Ditambahkan ke array
var array1 = [12, "foo", {name "joe"}, -2458]; var array2 = ["doe", 555, 100]; Array.prototype.push.apply (array1, array2); / * array1 nilainya [12, "foo", {name "joe"}, -2458, "doe", 555, 100] */Dapatkan nilai maksimum dan minimum dalam array
var angka = [5, 458, 120, -215]; var maxinnumbers = math.max.Apply (matematika, angka), // 458maxinnumbers = math.max.call (matematika, 5, 458, 120, -215); // 458
Nomor itu sendiri tidak memiliki metode maks, tetapi matematika memilikinya, sehingga kita dapat menggunakan metodenya dengan panggilan atau berlaku.
Verifikasi apakah itu array (asalkan metode tostring () belum ditulis ulang)
functionIsArray (obj) {return object.prototype.toString.call (obj) === '[array objek]';}Class (Pseudo) Array Menggunakan Metode Array
var domnodes = array.prototype.slice.call (document.geteLementsbyTagname ("*"));Ada struktur objek yang disebut pseudo-array di JavaScript. Yang lebih istimewa adalah objek argumen, dan ada juga orang-orang yang menyebut GetElementsByTagname, Document.childnodes, dll., Yang mengembalikan objek nodel, semuanya milik semu. Anda tidak dapat menggunakan Push, Pop, dan metode lain di bawah Array.
Tetapi kita dapat mengonversi array.prototype.slice.call menjadi array nyata dengan objek dengan atribut panjang, sehingga domnodes dapat menerapkan semua metode di bawah array.
Sangat memahami dan menggunakan Apply and Call
Mari kita pinjam pertanyaan wawancara untuk dipahami dan hubungi lebih dalam.
Tentukan metode log sehingga dapat proksi metode konsol.log. Solusi umum adalah:
function log (msg) {console.log (msg);} log (1); // 1Log (1,2); // 1Metode di atas dapat memecahkan kebutuhan paling dasar, tetapi ketika jumlah parameter yang dilewati tidak pasti, metode di atas akan gagal. Saat ini, Anda dapat mempertimbangkan menggunakan Apply atau Call. Perhatikan bahwa jumlah parameter yang disahkan di sini tidak pasti, jadi yang terbaik adalah menggunakan Apply. Metode ini adalah sebagai berikut:
function log () {console.log.Apply (konsol, argumen);}; log (1); // 1Log (1,2); // 1 2Persyaratan berikutnya adalah menambahkan dropout "(app)" ke setiap pesan log, seperti:
log ("halo dunia"); // (Aplikasi) Halo DuniaBagaimana melakukannya dengan lebih elegan? Pada saat ini, Anda perlu berpikir bahwa parameter argumen adalah pseudo-array, yang dikonversi menjadi array standar melalui array.prototype.slice.call, dan kemudian menggunakan metode array yang tidak tersesat, seperti ini:
function log () {var args = array.prototype.slice.call (argumen); args.unshift ('(app)'); console.log.apply (konsol, args);};mengikat penjelasan terperinci
Setelah berbicara tentang melamar dan menelepon, mari kita bicara tentang Bind. Metode Bind () sangat mirip untuk diterapkan dan dipanggil, dan juga dapat mengubah penunjuk ini di badan fungsi.
Penjelasan MDN adalah: metode Bind () akan membuat fungsi baru, yang disebut fungsi pengikat. Ketika fungsi pengikatan ini dipanggil, fungsi pengikatan akan menggunakan parameter pertama dari metode Bind () ketika dibuat sebagai ini, dan parameter kedua dari metode Bind () dan parameter selanjutnya ditambah parameter runtime fungsi pengikatan itu sendiri sebagai parameter dari fungsi asli untuk memanggil fungsi asli.
Mari kita lihat cara menggunakannya. Dalam mode monomer umum, kami biasanya menggunakan _This, itu, diri, dll. Untuk menyimpan ini sehingga kami dapat terus merujuknya setelah mengubah konteks. Seperti ini:
var foo = {bar: 1, eventBind: function () {var _this = this; $ ('. someclass'). on ('click', function (event) {/ * bertindak pada acara */console.log (_this.bar); // 1});}}Karena mekanisme spesifik Javascript, lingkungan konteks telah berubah di EventBind: function () {} ke $ ('. SomeClass'). On ('click', function (event) {}). Metode di atas menggunakan variabel untuk menyimpan ini berguna dan tidak ada masalah. Tentu saja, menggunakan bind () dapat menyelesaikan masalah ini dengan lebih elegan:
var foo = {bar: 1, eventBind: function () {$ ('. SomeClass'). on ('click', function (event) {/ * bertindak pada acara */console.log (this.bar); //1}.bind(this));}}Dalam kode di atas, bind () membuat fungsi. Ketika acara klik ini pasti akan dipanggil, kata kunci ini akan diatur ke nilai yang dilewati (di sini mengacu pada parameter yang dilewati ketika bind () dipanggil). Oleh karena itu, di sini kita lulus dalam konteks yang diinginkan ini (sebenarnya foo) ke fungsi Bind (). Kemudian, ketika fungsi callback dieksekusi, ini menunjuk ke objek Foo. Chestnut sederhana lainnya:
var bar = function () {console.log (this.x);} var foo = {x: 3} bar (); // UndefinedVar func = bar.bind (foo); func (); // 3Di sini kami membuat fungsi fungsi baru. Saat menggunakan bind () untuk membuat fungsi pengikatan, ketika dieksekusi, ini akan diatur ke foo, daripada ruang lingkup global seperti ketika kita memanggil bar ().
Ada pertanyaan yang menarik. Jika bind () dua kali berturut -turut, atau bind () tiga kali berturut -turut, lalu berapa nilai outputnya? Seperti ini:
var bar = function () {console.log (this.x);} var foo = {x: 3} var sed = {x: 4} var func = bar.bind (foo) .bind (sed); func (); //? var fiv = {x: 5} var func = bar.bind (foo) .bind (sed) .bind (fiv); func (); //? var fiv = {x: 5} var func = bar.bind (foo) .bind (sed) .bind (fiv); func (); //?Jawabannya adalah bahwa kedua kali masih akan mengeluarkan 3 alih -alih yang diharapkan 4 dan 5. Alasannya adalah bahwa dalam JavaScript, beberapa kali mengikat () tidak valid. Untuk alasan yang lebih dalam, implementasi BIND () setara dengan menggunakan fungsi untuk membungkus panggilan / berlaku secara internal. Bind kedua () setara dengan membungkus bind pertama () lagi, sehingga ikatan setelah kedua kalinya tidak dapat berlaku.
Terapkan, panggil, bind perbandingan
Jadi apa perbedaan dan perbedaan antara Apply, Call, dan Bind? Kapan Menggunakan Apply, Call, dan Kapan Menggunakan Bind. Kastanye sederhana:
var obj = {x: 81,}; var foo = {getx: function () {return this.x;}} console.log (foo.getx.bind (obj) ()); //81console.log(foo.getx.call(obj)); //81console.log(foo.getx.Apply(obj)); //81console.log(foo.getx.Apply(obj)); //81console.log(foo.getx.Apply(obj)); // 81Ketiga output adalah 81, tetapi perhatikan yang menggunakan metode Bind (), yang memiliki lebih banyak tanda kurung sesudahnya.
Artinya, perbedaannya adalah bahwa ketika Anda ingin mengubah konteks, tidak segera dijalankan, tetapi panggilan balik, gunakan metode Bind (). Terapkan/Panggilan menjalankan fungsi segera.
Mari kita ringkas lagi:
• Terapkan, panggil, bind semuanya digunakan untuk mengubah titik objek fungsi ini;
• Parameter pertama Apply, Call, dan Bind adalah objek yang ingin ditunjukkan, yaitu, konteks yang ingin Anda tentukan;
• Menerapkan, menelepon, dan mengikat semua dapat menggunakan parameter selanjutnya untuk meneruskan parameter;
• Bind mengembalikan fungsi yang sesuai, yang mudah dihubungi nanti; Terapkan dan panggilan dipanggil segera.
Di atas adalah penggunaan yang cerdas dari Apply, Call, dan Bind dalam JavaScript yang diperkenalkan kepada Anda oleh editor. Saya harap ini akan membantu Anda. Jika Anda memiliki pertanyaan, silakan tinggalkan saya pesan dan editor akan membalas Anda tepat waktu. Terima kasih banyak atas dukungan Anda ke situs web Wulin.com!