Làm cách nào để chuyển các đối số cho các hàm ẩn danh trong JavaScript?


83

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

Hãy xem mã mẫu này và tôi nghĩ bạn sẽ hiểu ý tôi:

<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 báo: it's workingsẽ xuất hiện. Tuy nhiên, myMessagebiến bên trong hàm ẩn danh là null.

jQuery sử dụng rất nhiều hàm ẩn danh, cách tốt nhất để truyền đối số đó là gì?


Câu trả lời:


72

Trường hợp cụ thể của bạn chỉ có thể được sửa chữa để hoạt động:

<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ẽ hoạt động vì hàm ẩn danh được tạo và gán như một trình xử lý cho phần tử sẽ có quyền truy cập vào các biến được xác định trong ngữ cảnh nơi nó được tạo.

Đối với bản ghi, một trình xử lý (mà bạn chỉ định thông qua thiết lập thuộc tính onxxx) mong đợi một đối số duy nhất nhận đối tượng đó là đối tượng sự kiện đang được DOM truyền vào và bạn không thể buộc chuyển đối số khác vào đó


27

Những gì bạn đã làm không hoạt động bởi vì bạn đang ràng buộc một sự kiện với 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 (nghĩa là JavaScript không biết về tham số của bạn trong hàm mà bạn đã liên kết với onclick nên không thể truyền bất kỳ thứ gì vào đó).

Tuy nhiên, bạn có thể làm điều này:

<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>

Tôi không thể hiểu, làm thế nào thông báo được hiểu bởi lambda gán giá trị trả về của nó cho myDelegate. Tôi đã thấy các lambdas như function (a, b) {// code here} (a, b);
Daniel N.

21

Sau đây là phương pháp sử dụng bao đóng để giải quyết vấn đề mà bạn tham khảo. Nó cũng tính đế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 để ngắn gọn.

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

Tôi đang học. Tại sao bạn chỉ định cho _message? Tại sao không chỉ sử dụng message?
Jonathan M

Trong trường hợp này, tôi đang làm điều đó để 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 bao đóng bên ngoài.
Gabriel

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

9

Bằng cách xóa tham số khỏi 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, hãy tìm kiếm 'các đóng javascript'


Tôi cần đọc về "javascript đóng" như bạn đã nêu .. Cảm ơn!
hakksor 22/10/08

5

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

Việc đóng có thể cho phép bạn tham chiếu đến 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ể muốn xem API sự kiện cụ thể của nó, ví dụ:

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

Điều này có một tùy chọn để chuyể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 hoạt động trong bộ thử nghiệm của tôi bao gồm mọi thứ từ IE6 +. Hàm ẩn danh nhận thức được đối tượng thuộc về nó, do đó bạn có thể truyền dữ liệu với đối tượng đang gọi nó (trong trường hợp này là myButton).


1

Thí 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>

Một thay đổi: eventObject = eventObject || window.event; Một thay đổi nữa: eventObject = eventObject || window.event || {};
mí mắt

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

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
}

0

Những gì bạn đã làm là tạo một hàm ẩn danh mới có một tham số duy nhất sau đó được gán cho biến cục bộ myMessage 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 giá trị trở thành null, nên hàm của bạn chỉ thực hiện cảnh báo (null).


0

Nếu bạn viết nó như thế nào

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

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.