I'm membaca buku tentang menulis kerangka kerja JavaScript dan menemukan potongan kode ini. Tapi aku don't memahami cara kerjanya, terutama yang mengikat.mengikat
penggunaan? Tidak ada yang memiliki petunjuk?
var bind = Function.prototype.bind;
var apply = bind.bind(bind.apply);
var fn = apply([].concat);
var a = [1, 2, 3], b = [4, [5, 6], 7];
fn(a, b);
//output [1, 2, 3, 4, 5, 6, 7]
Ini membawa saya kembali ke hari-hari memecahkan dan memperluas persamaan.
1 . Pertama, memungkinkan memperluas pertama menerapkan fungsi:
var bind = Function.prototype.bind;
var apply = bind.bind(bind.apply);
var fn = apply([].concat);
Mengubah ke:
var apply = Function.prototype.bind.bind(Function.prototype.bind.apply);
var fn = apply([].concat)
2 . Kedua, kita memperluas fn fungsi:
var fn = Function.prototype.bind.bind(Function.prototype.bind.apply)([].concat);
3 . Sekarang kita menciptakan js aljabar aturan dan mengganti mengikat.mengikat...()
doa dengan panggilan doa.
Sebenarnya kami menerapkan dasar penggantian pada gagasan bahwa:
someFunction.bind(arg1)(arg2) <==> someFunction.call(arg1, arg2)
Oleh karena itu kita dapat mengganti dan mendapatkan:
var fn = Function.prototype.bind.call(Function.prototype.bind.apply, [].concat);
4 . Untuk kedua js aljabar aturan kita menemukan bahwa:
someFn.mengikat.panggilan(sasaran, ...) <==> target.bind(...)
.
someFn
tidak penting di sini karena kami don't call bind() di atasnya. Kami memohon call
pada mengikat
- mengganti ini
itu someFn
dan untuk itu diganti dengan target
.
Oleh karena itu kita ganti mengikat.panggilan(target)
dengan target.mengikat alternatif
var fn = Function.prototype.bind.apply.bind([].concat)
5 . Jika yang terakhir permutasi juga melakukan doa () kita bisa melakukan ganti seperti:
fn([1, 2], [3, 4]) <==> [].concat.apply([1, 2], [3, 4])
Tapi kita hanya memiliki mengikat tanpa doa yang kita dapat mengganti dan setara dengan:
var fn = function (arg1, arg2) {
return [].concat.apply(arg1, arg2);
}
// instead arg1 and arg2 we could use more accurate arguments logic also.
Hasil Akhir
var fn = Function.prototype.bind.apply.bind([].concat)
// or
var fn = function (arg1, arg2) {
return [].concat.apply(arg1, arg2);
}
Tombol fn
fungsi mengambil concat
fungsi dan memungkinkan kita itu dalam gaya fungsional, tanpa menyebut dari sebuah objek. Bukan concat
binded dengan ini
pemanggil fn
berlaku pada arg1
seperti ini
dan arg2
seperti yang lain params untuk rangkaian untuk arg1
.
fn([1, 2], [3, [5, 6], 4])
// [1, 2, 3, 5, 6, 4]
Karena Fungsi.prototipe.mengikat
itu sendiri adalah sebuah fungsi, itu mewarisi dirinya sendiri sebagai metode.
Biasanya, mengikat disebut sebagai metode contoh dari suatu fungsi tertentu, tetapi kita dapat rebind itu untuk Fungsi.prototipe.menerapkan
dan return yang lebih tinggi agar fungsi.
Kurang singkat cara penulisan ini akan sama:
function apply (fn) {
return function (a, b) {
return fn.apply(a, b)
}
}
Kita harus berpikir sedikit tentang apa yang mengikat
sebenarnya di belakang layar. Untuk kasar pendekatan, ia bekerja seperti ini:
function bind(fn, ...bound) {
return (...other) => this.call(fn, ...bound, ...other);
}
(Ingat bahwa leksikal ini
mengacu pada fungsi yang mengikat
disebut.) Jadi mengambil
apply = bind.bind(bind.apply);
dan manual memperluas mengikat
diri kita sendiri, kita mendapatkan:
apply = (...other) => bind.call(bind.apply, ...other);
Kami're hanya tertarik dalam melewati satu argumen, yang merupakan fungsi. Mudah-mudahan ini juga berarti bahwa terapkan
properti adalah sama seperti yang mengikat
:
apply = (fn) => bind.call(fn.apply, fn);
Tapi mengikat
adalah (mudah-mudahan) itu sendiri juga pada fn.menerapkan
's prototipe, sehingga kita dapat menyederhanakan lebih lanjut ke:
apply = (fn) => fn.apply.bind(fn);
Kami're sekarang dalam posisi untuk memperluas mengikat
lagi:
apply = (fn) => (...other) => fn.apply.call(fn, ...other);
Kali ini, kami ingin dua argumen, dan panggilan untuk memanggil
juga dapat disederhanakan:
apply = (fn) => (obj, args) => fn.apply(obj, args);
Kami're sekarang dalam posisi untuk memanggil terapkan
on [].concat
:
fn = (obj, args) => [].concat.apply(obj, args);
obj
harus array untuk ini untuk bekerja, sehingga ini memudahkan untuk:
fn = (obj, args) => obj.concat(...args);
Dan dalam contoh kita berakhir dengan
[1, 2, 3].concat(4, [5, 6], 7)
yang mengembalikan hasil yang diharapkan.
bind()
metode menciptakan sebuah instance baru dari fungsi untuk nilai yang disahkan menjadi bind()
.
Di sini kita panggil Fungsi.prototipe.mengikat.menerapkan(Fungsi.prototipe, [null].concat(argumen));
dengan membobol terpisah eksekusi kode unit.
Tujuannya adalah untuk memanggil terapkan
; untuk lulus ke fungsi semula sebagai param dan kemudian array argumen.
Kode ini memiliki variabel yang berbeda untuk masing-masing proses yang terlibat untuk mencapai mengikat dengan dinamis params.
var bind=Function.prototype.bind;
// the bind function is assigned to a var
var apply=bind.bind(bind.apply);
// a new function apply is created which is nothing but bind.apply
var fn=apply([].concat);
// the apply function is defined and now we have final function
that will concat array.
Dua baris terakhir adalah untuk melaksanakan fn
fungsi dengan melewati dua parameter
var a=[1,2,3],b=[4,[5,6],7]; fn(a,b);