Những gì Pekka nói là đúng, nhưng tôi muốn giải thích thêm một chút với một ví dụ sẽ giúp giải thích cho những người không hiểu đầy đủ về con trỏ hoặc đại biểu hàm.
Tôi sẽ không sử dụng window.onloadbởi vì đó là một chút giả thiết để chứng minh. Thay vào đó, tôi sẽ sử dụng một hàm nhân đơn giản để demo:
function Multiply(operator, operand) {
return operator * operand;
}
Điều này cũng có thể được viết:
Multiply = function(operator, operand) {
return operator * operand;
}
Mặc dù trong ví dụ đầu tiên, hàm ý có thể không rõ ràng, nhưng ví dụ thứ hai cho thấy rõ ràng hơn rằng chúng ta đang gán một hàm có 2 tham số cho một biến được gọi Multiplyvà khái niệm hàm dưới dạng phép gán này là phổ biến trong JavaScript. Đây là một minh chứng nhỏ về thực tế rằng các hàm là "công dân hạng nhất" , nghĩa là, chúng có thể được truyền xung quanh chính xác như thể chúng ta truyền xung quanh các giá trị.
Vì vậy, bây giờ đến sự khác biệt của nhiệm vụ:
var operator = 3;
var operand = 4;
var ret = Multiply(operator, operand);
Tại điểm xác định biến ret, Multiplyđược thực thi và giá trị trả về được gán - rettrở thành bằng 12.
Hãy thử lại theo cách khác:
var operator = 3;
var operand = 4;
var ret = Multiply;
Bây giờ, tại điểm xác định ret, rettrở thành Multiplyhàm của bạn thay vì là kết quả thu được từ Multiplyhàm của bạn . Các lệnh gọi tới ret()sẽ khiến Multiplyhàm của bạn được thực thi và bạn có thể gọi nó chính xác như thể bạn đã gọi Multiply(operator, operand):
var out = ret(3, 4);
giống như
var out = Multiply(3, 4);
Bạn đã nói một cách hiệu quả rằng bạn sẽ sử dụng retnhư một đại biểu cho Multiply(). Khi gọi ret, chúng tôi thực sự đang đề cập đến Multiplyhàm.
Trở lại của bạn window.onload. Hãy nghĩ về điều này như:
window.onload = function() {
//Doing what all good window.onload functions should do...
}
initAll = function() {
return 12;
}
Vì vậy, như bạn có thể thấy, window.onloadlà một chức năng giống như bất kỳ chức năng nào khác, không có gì đặc biệt về nó. Bạn có thể gán cho nó một giá trị, gán cho nó một chức năng, vô hiệu hóa nó nếu bạn muốn - vấn đề là không có gì đặc biệt window.onloadhơn là về chức năng của riêng bạn. Điều duy nhất hơi khác là nó được gọi bởi cửa sổ khi nó được tải. [Tuyên bố từ chối trách nhiệm: Tôi chưa bao giờ thực sự hủy bỏ các chức năng cửa sổ, vì vậy tôi không chắc liệu điều này có gây ra hậu quả tiêu cực hay không. Người ta hy vọng họ sẽ kiểm tra xem một hàm có được gán hay không trước khi gọi nó tức là if (window.onload) window.onload();].
Bây giờ gọi initAll()những gì chúng ta đang nói là:
window.onload = initAll();
cũng có thể nói:
window.onload = 12;
Nhưng khi chúng ta nói initAllmà không có dấu ngoặc đơn, điều chúng ta thực sự đang nói là: Tôi muốn thay thế bất kỳ hàm window.onload của tôi là gì, bằng một hàm mới - tức là tôi muốn thay thế nó bằng initAllhàm của mình , để mọi lệnh gọi window.onloadchạy initAllmã.
Vì thế:
window.onload = function() {
//Doing what all good window.onload functions should do...
}
được thay thế bằng:
window.onload = function() {
return 12;
}
Vì vậy, bất kỳ lệnh gọi nào window.onloadsẽ thực thi initAllchức năng của bạn thay vì bất kỳ lệnh nào window.onloadban đầu. Bạn đã thay thế chức năng ban đầu bằng chức năng mới của mình.
Trên thực tế, bạn có thể viết:
window.onload = function() {
//Write all your init code right in here instead of having a separate
//initAll function.
}
Một ví dụ khác có thể chứng minh tốt hơn là:
var d = new Date();
var currentTime = d.getTime();
Bất kể thời gian là tại thời điểm dđược xác định cuối cùng sẽ được gán cho currentTime. Tuyệt vời, nhưng điều đó chỉ hữu ích nếu chúng ta muốn tìm hiểu thời gian hàm chứa mã đó được gọi - tức là tại thời gian tải trang. Điều gì sẽ xảy ra nếu chúng ta muốn thời gian hiện tại bất kỳ lúc nào currentTimeđược gọi?
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
Chú ý cách chúng ta gọi b()trong bài tập cvà của mình dchính xác như cách chúng ta có thể gọi currentTime()?