ผ่านฟังก์ชั่นที่มีพารามิเตอร์เป็นพารามิเตอร์หรือไม่?


151

เป็นไปได้ไหมที่จะส่งผ่านฟังก์ชัน javascript ที่มีพารามิเตอร์เป็นพารามิเตอร์?

ตัวอย่าง:

$(edit_link).click( changeViewMode( myvar ) );

5
ดูเหมือนว่า JQuery และเป็นไปได้มาก แต่ก็ไม่เกี่ยวข้อง การใช้หรือพารามิเตอร์และฟังก์ชั่นจะเหมือนกันโดยไม่คำนึงถึงไลบรารี Javascript ที่คุณใช้
Guffa

@Guffa - ผมสงสัยว่าถ้ามันควรจะติดแท็กด้วย jQuery
รัสบแคม

1
@Lucia โปรดพิจารณาเปลี่ยนคำตอบที่ได้รับการยอมรับไปนี้
MichałPerłakowski

หากคุณกำลังทำงานกับ React ให้พิจารณาstackoverflow.com/questions/41369497/…
Michael Freidgeim

คำตอบ:


244

ใช้ "การปิด":

$(edit_link).click(function(){ return changeViewMode(myvar); });

สิ่งนี้จะสร้าง wrapper ฟังก์ชันชั่วคราวแบบไม่ระบุชื่อที่รู้เกี่ยวกับพารามิเตอร์และส่งผ่านไปยังการประยุกต์ใช้การโทรกลับจริง


3
หากคุณต้องการเรียกใช้ฟังก์ชันบนวัตถุคุณจะต้องเรียก bind () myObj.click (function () {this.doSomething ();} .bind (myObj)); นั่นจะทำให้ "นี่" เป็น myObj
อีไล

1
นี่ไม่ใช่ปัญหาด้านประสิทธิภาพเมื่อต้องรับมือกับสิ่งเหล่านี้มากมายใช่ไหม เช่นคุณกำลังแสดงผลการกดในแถวและคุณมี 10,000 แถว สิ่งนี้จะสร้าง wrapper ฟังก์ชันชั่วคราวแบบไม่ระบุชื่อใหม่สำหรับแต่ละแถว มีวิธีอื่นที่จะทำหรือไม่
Joshua Pinter

@JoshuaPinter เทคนิคนั้นไม่ได้เป็นปัญหา หากคุณต้องการฟังก์ชั่นเดียวกันเรียก 10,000 ครั้งคุณสามารถบันทึกเสื้อคลุมในตัวแปรเพื่อให้คุณสร้างมันเพียงครั้งเดียว หากคุณต้องการผ่าน 10,000 บริบทที่แตกต่างกันมีน้อยที่คุณสามารถทำได้ ระวังการปรับให้เหมาะสมก่อนกำหนด: เช่นเดียวกับประสิทธิภาพคุณจำเป็นต้องวัดเพื่อดูว่ามีปัญหาหรือไม่ เอ็นจิ้น JavaScript ของวันนี้มีประสิทธิภาพมากและอาจปรับโค้ดให้น่าแปลกใจ
เฟอร์ดินานด์เบเยอร์

@ FerdinandBeyer สุดยอดขอบคุณสำหรับเคล็ดลับ เพื่อนบอกฉันว่ามันเป็นการฝึกฝนที่ไม่ดีและคุณควรใช้วิธีการthis.myFunction = this.myFunction.bind(this)ของคุณconstructorแทน แต่อย่างที่คุณพูดเมื่อคุณต้องผ่านบริบทที่แตกต่างกันไปสำหรับแต่ละคนเช่นแถวต่างๆที่คุณคลิกเพื่อเปิดหน้ารายละเอียดของแถวนั้นมันไม่สามารถหลีกเลี่ยงได้
Joshua Pinter

@FerdinandBeyer สมมติว่า myvar เป็นสตริงและเปลี่ยนแปลงระหว่างการเรียกใช้งานต่อเนื่องสองครั้งของการส่งผ่าน changeViewMode เป็นการปิด แต่ changeViewMode จะรับค่าแรกของ myvar เสมอฉันต้องการเรียกฟังก์ชันปิดที่มีค่าอาร์กิวเมนต์ที่แตกต่างกันที่กำหนดให้กับตัวแปร myvar เดียวกัน
nmxprime

42

Function.prototype.bind()ใช้ การอ้างอิง MDN:

bind()วิธีการสร้างฟังก์ชั่นใหม่ที่เรียกว่าเมื่อมีของthisชุดคำหลักเพื่อให้คุ้มค่ากับการให้ลำดับของการขัดแย้งก่อนหน้านี้ที่ให้บริการใด ๆ เมื่อฟังก์ชั่นใหม่ที่เรียกว่า

ได้รับการสนับสนุนโดยเบราว์เซอร์หลักทั้งหมดรวมถึง IE9 +

รหัสของคุณควรมีลักษณะเช่นนี้:

$(edit_link).click(changeViewMode.bind(null, myvar));

หมายเหตุด้านข้าง: ฉันคิดว่าคุณอยู่ในบริบทโลกเช่นthisตัวแปรคือwindow; มิฉะนั้นใช้แทนthisnull


ขอบคุณสิ่งนี้ช่วยฉัน ใช้มันแบบนี้:$.ajax(url).done(handler.bind(this, var1, var2));
โทมัส

2
ตัวเลือกใดดีที่สุด ใช้การปิดหรือใช้ฟังก์ชั่นผูกหรือไม่ โปรดแจ้งให้เราทราบหากมีผลกระทบต่อประสิทธิภาพการทำงาน
Varun


15

ไม่ แต่คุณสามารถผ่านได้โดยไม่มีพารามิเตอร์และทำสิ่งนี้:

$(edit_link).click(
  function() { changeViewMode(myvar); }
);

ดังนั้นคุณจะผ่านฟังก์ชั่นนิรนามโดยไม่มีพารามิเตอร์จากนั้นฟังก์ชั่นนั้นจะเรียกใช้ฟังก์ชั่นที่กำหนดพารามิเตอร์ของคุณพร้อมกับตัวแปรในการปิด



7

หรือถ้าคุณใช้ es6 คุณควรจะสามารถใช้ฟังก์ชั่นลูกศรได้

$(edit_link).click(() => changeViewMode(myvar));

2

คุณสามารถทำได้

var message  = 'Hello World';

var callback = function(){
alert(this)
}.bind(message);

แล้ว

function activate(callback){
  callback && callback();
}

activate(callback);

หรือถ้าโทรกลับของคุณมีตรรกะที่ยืดหยุ่นมากขึ้นคุณสามารถส่งผ่านวัตถุ

การสาธิต


2

นี่คือตัวอย่างต่อไปนี้แนวทางของ Ferdinand Beyer:

function function1()
{
    function2(function () { function3("parameter value"); });
}
function function2(functionToBindOnClick)
{
    $(".myButton").click(functionToBindOnClick);
}
function function3(message) { alert(message); }

ในตัวอย่างนี้ "ค่าพารามิเตอร์" ถูกส่งผ่านจาก function1 ถึง function3 ถึง function2 โดยใช้ฟังก์ชันการตัด

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.