สิ่งที่ Pekka พูดนั้นถูกต้อง แต่ฉันต้องการอธิบายรายละเอียดเล็กน้อยพร้อมกับตัวอย่างที่จะช่วยอธิบายให้คนที่ไม่เข้าใจตัวชี้ฟังก์ชันหรือผู้รับมอบสิทธิ์ได้อย่างเต็มที่
ฉันจะไม่ใช้window.onloadเพราะมันถูกสร้างขึ้นมาเพื่อแสดงให้เห็น ฉันจะใช้ฟังก์ชันคูณอย่างง่ายเพื่อสาธิตแทน:
function Multiply(operator, operand) {
return operator * operand;
}
สิ่งนี้สามารถเขียนได้อย่างเท่าเทียมกัน:
Multiply = function(operator, operand) {
return operator * operand;
}
แม้ว่าในตัวอย่างแรกความหมายอาจไม่ชัดเจน แต่ตัวอย่างที่สองแสดงให้เห็นอย่างชัดเจนยิ่งขึ้นว่าเรากำลังกำหนดฟังก์ชันที่มีพารามิเตอร์ 2 ตัวให้กับตัวแปรที่เรียกว่าMultiplyและแนวคิดของฟังก์ชันนี้เป็นการกำหนดเป็นเรื่องธรรมดาใน JavaScript นี่เป็นการแสดงให้เห็นเล็กน้อยถึงความจริงที่ว่าฟังก์ชั่นเป็น"พลเมืองชั้นหนึ่ง"กล่าวคือสามารถส่งผ่านไปรอบ ๆ ได้ราวกับว่าเรากำลังส่งผ่านค่านิยม
ตอนนี้ถึงความแตกต่างของการมอบหมาย:
var operator = 3;
var operand = 4;
var ret = Multiply(operator, operand);
ณ จุดกำหนดตัวแปร ret Multiplyจะถูกเรียกใช้งานและกำหนดค่าส่งคืน - retจะเท่ากับ 12
ลองอีกครั้งด้วยวิธีอื่น:
var operator = 3;
var operand = 4;
var ret = Multiply;
ตอนนี้ที่จุดของการกำหนดret, retกลายเป็นของMultiplyฟังก์ชั่นเมื่อเทียบกับการเป็นผลที่ได้รับจากMultiplyการทำงาน การโทรไปที่ret()จะทำให้Multiplyฟังก์ชันของคุณถูกเรียกใช้งานและคุณสามารถเรียกมันได้เหมือนกับที่คุณเรียกMultiply(operator, operand):
var out = ret(3, 4);
เหมือนกับ
var out = Multiply(3, 4);
คุณได้อย่างมีประสิทธิภาพบอกว่าคุณจะใช้เป็นตัวแทนสำหรับret Multiply()เมื่อโทรretเราหมายถึงMultiplyฟังก์ชันจริงๆ
กลับไปที่window.onloadไฟล์. คิดว่าสิ่งนี้เป็น:
window.onload = function() {
//Doing what all good window.onload functions should do...
}
initAll = function() {
return 12;
}
อย่างที่คุณเห็นwindow.onloadมันเป็นฟังก์ชันเหมือนกับฟังก์ชันอื่น ๆ ไม่มีอะไรพิเศษเกี่ยวกับมัน คุณสามารถกำหนดค่ากำหนดฟังก์ชันเป็นโมฆะได้หากต้องการประเด็นก็คือไม่มีอะไรพิเศษไปwindow.onloadกว่าฟังก์ชันของคุณเอง สิ่งเดียวที่แตกต่างกันเล็กน้อยคือถูกเรียกโดยหน้าต่างเมื่อโหลด [คำเตือน: ฉันไม่เคยลบล้างฟังก์ชันของหน้าต่างเลยฉันไม่แน่ใจว่าสิ่งนี้จะทำให้เกิดผลกระทบเชิงลบหรือไม่ เราหวังว่าพวกเขาจะตรวจสอบดูว่ามีการกำหนดฟังก์ชันก่อนที่จะเรียกมันว่า ie if (window.onload) window.onload();]
ตอนนี้เรียกinitAll()สิ่งที่เรากำลังพูดคือ:
window.onload = initAll();
ซึ่งอาจกล่าวได้ว่า:
window.onload = 12;
แต่เมื่อเราพูดinitAllโดยไม่มีวงเล็บสิ่งที่เรากำลังพูดจริงๆคือ: ฉันต้องการแทนที่ฟังก์ชัน window.onload ของฉันด้วยฟังก์ชันใหม่นั่นคือฉันต้องการแทนที่ด้วยinitAllฟังก์ชันของฉันเพื่อให้การเรียกใช้window.onloadงานของฉันinitAllรหัส.
ดังนั้น:
window.onload = function() {
//Doing what all good window.onload functions should do...
}
ถูกแทนที่ด้วย:
window.onload = function() {
return 12;
}
ดังนั้นการเรียกใช้ใด ๆwindow.onloadจะเรียกใช้initAllฟังก์ชันของคุณแทนสิ่งที่window.onloadมีมา แต่เดิม คุณได้แทนที่ฟังก์ชันเดิมด้วยฟังก์ชันใหม่ของคุณ
ในความเป็นจริงคุณสามารถเขียนได้เท่า ๆ กัน:
window.onload = function() {
//Write all your init code right in here instead of having a separate
//initAll function.
}
อีกตัวอย่างหนึ่งที่อาจแสดงให้เห็นได้ดีกว่าคือ:
var d = new Date();
var currentTime = d.getTime();
ไม่ว่าเวลาเป็นเวลาที่ถูกกำหนดขึ้นปลายมอบหมายให้d currentTimeเยี่ยมมาก แต่จะมีประโยชน์ก็ต่อเมื่อเราต้องการทราบว่าฟังก์ชันที่มีโค้ดนั้นถูกเรียกใช้เวลาใดเช่นในเวลาโหลดหน้า จะเป็นอย่างไรถ้าเราต้องการให้เวลาปัจจุบันcurrentTimeเรียกว่าเวลาใด?
var currentTime = function() {
var d = new Date();
return d.getTime();
}
var a = currentTime(); //The current time at the point a is defined...
var b = currentTime; //b is a functional reference to currentTime...
var c = b(); //The current time when variable c is defined
var d = c; //The current time when variable c was defined
สังเกตว่าเราโทรb()เข้าcและdมอบหมายงานตรงกับที่เราโทรได้currentTime()อย่างไร?