2008-10-22 48 views
68

Tôi đang cố gắng tìm ra cách chuyển đối số cho một hàm ẩn danh trong JavaScript.Làm cách nào để chuyển đối số cho các hàm ẩn danh trong JavaScript?

Kiểm tra mẫu mã này và tôi nghĩ rằng bạn sẽ thấy những gì tôi có nghĩa là:

<input type="button" value="Click me" id="myButton" /> 

<script type="text/javascript"> 
    var myButton = document.getElementById("myButton"); 
    var myMessage = "it's working"; 
    myButton.onclick = function(myMessage) { alert(myMessage); }; 
</script> 

Khi nhấp vào nút thông điệp: sẽ xuất hiện. Tuy nhiên, biến số myMessage bên trong hàm ẩn danh là null.

jQuery sử dụng rất nhiều chức năng ẩn danh, cách tốt nhất để vượt qua đối số đó là gì?

+0

đóng cửa: http://blog.niftysnippets.org/2008/02/closures-are-not-complicated.html – mishal153

Trả lời

62

trường hợp cụ thể của bạn chỉ có thể được sửa chữa để được làm việc:

<script type="text/javascript"> 
    var myButton = document.getElementById("myButton"); 
    var myMessage = "it's working"; 
    myButton.onclick = function() { alert(myMessage); }; 
</script> 

Ví dụ này sẽ làm việc vì các chức năng ẩn danh tạo và gán như một handler cho phần tử sẽ được tiếp cận với các biến định nghĩa trong bối cảnh nơi nó được tạo.

Đối với hồ sơ, một handler (mà bạn chỉ định thông qua việc thiết XXX tài sản) hy vọng đối số duy nhất để lấy đó là đối tượng sự kiện được thông qua bởi DOM, và bạn không thể ép buộc đi qua lập luận khác trong đó

9

Bằng cách loại bỏ các tham số từ hàm ẩn danh sẽ có sẵn trong phần thân.

myButton.onclick = function() { alert(myMessage); }; 

Để biết thêm thông tin tìm kiếm cho 'javascript đóng cửa'

+0

tôi cần phải đọc lên trên "đóng cửa javascript" như bạn đã nêu .. Cảm ơn! – hakksor

22

Những gì bạn đã thực hiện không làm việc vì bạn đang ràng buộc một sự kiện vào một hàm. Như vậy, đó là sự kiện xác định các tham số sẽ được gọi khi sự kiện được nâng lên (tức là JavaScript không biết về tham số của bạn trong hàm bạn đã ràng buộc trên onclick vì vậy không thể chuyển bất kỳ thứ gì vào nó).

Bạn có thể làm điều này tuy nhiên:

<input type="button" value="Click me" id="myButton"/> 

<script type="text/javascript"> 

    var myButton = document.getElementById("myButton"); 

    var myMessage = "it's working"; 

    var myDelegate = function(message) { 
     alert(message); 
    } 

    myButton.onclick = function() { 
     myDelegate(myMessage); 
    }; 

</script> 
+0

Tôi không thể thấy, thông điệp được hiểu bởi lambda gán giá trị trả về của nó cho myDelegate. Tôi đã xem các lambdas như chức năng (a, b) { // mã ở đây } (a, b); –

0

gì bạn đã làm được tạo ra một chức năng ẩn danh mới mà phải mất một tham số duy nhất mà sau đó được giao cho MyMessage biến cục bộ bên trong hàm. Vì không có đối số nào thực sự được truyền, và các đối số không được truyền qua một giá trị trở thành null, hàm của bạn chỉ làm cảnh báo (null).

0

Nếu bạn viết nó như

myButton.onclick = function() { alert(myMessage); }; 

Nó sẽ làm việc, nhưng tôi không biết nếu đó là câu trả lời câu hỏi của bạn.

1

Ví dụ:

<input type="button" value="Click me" id="myButton"> 
<script> 
    var myButton = document.getElementById("myButton"); 
    var test = "zipzambam"; 
    myButton.onclick = function(eventObject) { 
     if (!eventObject) { 
      eventObject = window.event; 
     } 
     if (!eventObject.target) { 
      eventObject.target = eventObject.srcElement; 
     } 
     alert(eventObject.target); 
     alert(test); 
    }; 
    (function(myMessage) { 
     alert(myMessage); 
    })("Hello"); 
</script> 
+0

Một thay đổi: eventObject = eventObject || window.event; Một thay đổi khác: eventObject = eventObject || window.event || {}; – eyelidlessness

+0

Một thay đổi khác: eventObject.target = eventObject.target || eventObject.srcElement || vô giá trị; – eyelidlessness

1

Các đại biểu:

function displayMessage(message, f) 
{ 
    f(message); // execute function "f" with variable "message" 
} 

function alerter(message) 
{ 
    alert(message); 
} 

function writer(message) 
{ 
    document.write(message); 
} 

Chạy chức năng DisplayMessage:

function runDelegate() 
{ 
    displayMessage("Hello World!", alerter); // alert message 

    displayMessage("Hello World!", writer); // write message to DOM 
} 
5

xử lý tổ chức sự kiện mong đợi một tham số đó là trường hợp đã bị sa thải. Bạn tình cờ đổi tên thành 'myMessage' và do đó bạn đang cảnh báo đối tượng sự kiện thay vì thông điệp của bạn.

Việc đóng có thể cho phép bạn tham chiếu biến mà bạn đã xác định bên ngoài hàm, tuy nhiên nếu bạn đang sử dụng Jquery, bạn có thể xem API cụ thể của sự kiện, ví dụ:

http://docs.jquery.com/Events/bind#typedatafn

Tùy chọn này có tùy chọn truyền dữ liệu của riêng bạn.

3
<input type="button" value="Click me" id="myButton" /> 

<script type="text/javascript"> 
    var myButton = document.getElementById("myButton"); 

    myButton.myMessage = "it's working"; 

    myButton.onclick = function() { alert(this.myMessage); }; 


</script> 

Điều này làm việc trong bộ thử nghiệm bao gồm mọi thứ từ IE6 +. Hàm ẩn danh nhận thức được đối tượng mà nó thuộc về do đó bạn có thể chuyển dữ liệu với đối tượng đang gọi nó (trong trường hợp này là myButton).

20

Sau đây là phương pháp sử dụng các bao đóng để giải quyết vấn đề mà bạn giới thiệu. Nó cũng đưa vào tài khoản thực tế là có thể thay đổi thông điệp theo thời gian mà không ảnh hưởng đến ràng buộc. Và nó sử dụng jQuery để gọn gàng.

var msg = (function(message){ 
    var _message = message; 
    return { 
    say:function(){alert(_message)}, 
    change:function(message){_message = message} 
    }; 
})("My Message"); 
$("#myButton").click(msg.say); 
+0

Tôi đang học. Tại sao bạn gán cho '_message'? Tại sao không chỉ sử dụng 'tin nhắn'? –

+0

Trong trường hợp này tôi đang thực hiện nó để phạm vi bên trong của phương thức thay đổi có thể có chữ ký hợp lệ, nếu không sẽ không có cách nào thay đổi giá trị thông báo trong phần đóng bên ngoài. – Gabriel

+0

Câu trả lời tuyệt vời bằng cách đóng cửa. Tuy nhiên, tôi sẽ đổi tên đối số hàm "thay đổi" vì "thông báo" là gây hiểu nhầm, cần rõ ràng hơn là nó không liên quan đến đối số "thông điệp" bên ngoài. chức năng đó có thể được tái cấu trúc như thế này: thay đổi: chức năng (newmessage) {_ message = newmessage} –

Các vấn đề liên quan