Dalam Javascript, bagaimana cara mengikat argumen ke suatu fungsi tanpa mengikat this
parameter?
Sebagai contoh:
//Example function.
var c = function(a, b, c, callback) {};
//Bind values 1, 2, and 3 to a, b, and c, leave callback unbound.
var b = c.bind(null, 1, 2, 3); //How can I do this without binding scope?
Bagaimana saya bisa menghindari efek samping karena harus mengikat ruang lingkup fungsi (misalnya, pengaturan this
= null) juga?
Edit:
Maaf bila membingungkan. Saya ingin mengikat argumen, kemudian dapat memanggil fungsi terikat nanti dan membuatnya berperilaku persis seperti jika saya memanggil fungsi asli dan meneruskannya ke argumen terikat:
var x = 'outside object';
var obj = {
x: 'inside object',
c: function(a, b, c, callback) {
console.log(this.x);
}
};
var b = obj.c.bind(null, 1, 2, 3);
//These should both have exact same output.
obj.c(1, 2, 3, function(){});
b(function(){});
//The following works, but I was hoping there was a better way:
var b = obj.c.bind(obj, 1, 2, 3); //Anyway to make it work without typing obj twice?
Saya masih baru dalam hal ini, maaf atas kebingungannya.
Terima kasih!
javascript
Mengilhami
sumber
sumber
this
?var b = c.bind(this, 1,2,3);
bind()
benull
? Sepertinya bekerja dengan baik di FF.this
sepenuhnya melepaskan JavaScript. Itu selalu berarti sesuatu . Jadi mengikatthis
kethis
fungsi penutup sangat masuk akal.Jawaban:
Anda dapat melakukan ini, tetapi sebaiknya hindari menganggapnya sebagai "mengikat" karena itulah istilah yang digunakan untuk menetapkan nilai "ini". Mungkin menganggapnya sebagai "membungkus" argumen menjadi suatu fungsi?
Apa yang Anda lakukan adalah membuat fungsi yang memiliki argumen yang diinginkan dibangun di dalamnya melalui closures:
Semoga saya mendapatkan sintaks di sana. Apa yang dilakukannya adalah membuat fungsi yang disebut withWrappedArguments () (menjadi pedantic, ini adalah fungsi anonim yang ditetapkan ke variabel) yang dapat Anda panggil kapan saja di mana saja dan akan selalu bertindak dengan actualArg1Value dan actualArg2Value, dan apa pun yang ingin Anda masukkan sana. Anda juga dapat membuatnya menerima argumen lebih lanjut pada saat menelepon jika Anda mau. Rahasianya adalah tanda kurung setelah kurung kurawal tutup. Ini menyebabkan fungsi luar segera dieksekusi, dengan nilai yang diteruskan, dan menghasilkan fungsi dalam yang bisa dipanggil nanti. Nilai yang diteruskan kemudian dibekukan pada saat fungsi tersebut dibuat.
Inilah yang secara efektif dilakukan bind, tetapi dengan cara ini secara eksplisit bahwa argumen yang dibungkus hanyalah penutupan pada variabel lokal, dan tidak perlu mengubah perilaku ini.
sumber
f(x,y)
kami inginf(x)(y)
ataug=f(x); g(y)
. Jadi kami akan mengubahnyaf=(x,y)=>x+y
menjadif=(x)=>(y)=>x+y
."Di ES6, ini mudah dilakukan dengan menggunakan parameter istirahat sehubungan dengan operator sebaran .
Jadi kita bisa mendefinisikan fungsi
bindArgs
yang berfungsi seperti itubind
, kecuali hanya argumen yang terikat, tetapi tidak konteksnya (this
).Kemudian, untuk fungsi
foo
dan objek tertentuobj
, pernyataansetara dengan
di mana hanya argumen pertama dan kedua yang terikat
bar
, sementara konteks yangobj
ditentukan dalam pemanggilan digunakan dan argumen tambahan ditambahkan setelah argumen terikat. Nilai pengembalian hanya diteruskan.sumber
let
danconst
, yang belum tersedia pada saat saya pertama kali memposting ini. Ini diperbarui sekarang.Dalam
bind
metode asli ,this
nilai dalam fungsi hasil hilang. Namun, Anda dapat dengan mudah mengode ulang shim umum untuk tidak menggunakan argumen untuk konteksnya:sumber
Function
tetapi itu menghemat banyak waktu dan beberapa solusi buruk. Terima kasihbind
. Anda dapat dengan mudah mengubahnya menjadifunction bindArgs(fn){ …, args = slice.call(arguments, 1); …}
this
ingin melakukannyaa
. Anda bisa menggunakanbind
sebagai gantinya, tentu saja. Namun, OP secara eksplisit tidak peduli denganthis
nilai dan menginginkan fungsi parsial yang tidak terikat.this
adalah fungsi yang digunakanthis
, tetapi mereka tidak ingin mengikatnya pada saat itu. Juga, bagian dalam pertanyaan OP itu//These should both have exact same output.
kontradiktif dengan bagian lain darinya.bind
tidak berfungsi sama sekali dengan konstruktor, fungsi terikat tidak memiliki.prototype
. Tidak,Function.prototype !== mymethod.prototype
Satu lagi penerapan kecil hanya untuk kesenangan:
Cara Penggunaan:
sumber
sumber
const curry = (fn, ...curryArgs) => (...args) => fn(...curryArgs, args)
Agak sulit untuk mengatakan dengan tepat apa yang akhirnya ingin Anda lakukan karena contohnya agak sewenang-wenang, tetapi Anda mungkin ingin melihat sebagian (atau kari): http://jsbin.com/ifoqoj/1/edit
Tautan ke artikel John Resig: http://ejohn.org/blog/p Partial-functions-in-javascript/
sumber
partial
kebutuhan Anda untuk dipanggil denganundefined
argumen agar berfungsi - bukan yang diharapkan, dan rusak pada fungsi yang mengambil sejumlah parameter sewenang-wenang.this
objeknya masih kacau balau. Lihat di: jsbin.com/ifoqoj/4/editMungkin Anda ingin mengikat referensi ini di bagian terakhir tetapi kode Anda: -
Sudah diterapkan pengikatan misalnya ini dan nanti Anda tidak dapat mengubahnya. Apa yang akan saya sarankan agar gunakan referensi juga sebagai parameter seperti ini: -
sumber
Gunakan
protagonist
!Pada dasarnya, fungsi yang ingin Anda sampaikan params menjadi proxy yang dapat Anda panggil untuk meneruskan variabel, dan mengembalikan fungsi yang sebenarnya ingin Anda lakukan.
Semoga ini membantu!
sumber
Seorang pengguna anonim memposting info tambahan ini:
sumber
Nah untuk contoh yang Anda berikan, ini akan berhasil
Jika Anda ingin menjamin parameter penutup:
Tetapi jika demikian, Anda harus tetap berpegang pada solusi Anda:
Itu cara yang lebih baik.
sumber
Sederhana seperti itu?
Solusi yang lebih umum:
sumber
Menggunakan LoDash Anda dapat menggunakan
_.partial
fungsi tersebut.sumber
Mengapa tidak menggunakan pembungkus di sekitar fungsi untuk menyimpan ini sebagai mitos?
sumber
jQuery 1.9 membawa fitur itu dengan fungsi proxy.
Contoh:
sumber
Kasus penggunaan Jquery:
sebagai gantinya:
Gunakan ini:
sumber