2012-06-19 32 views
6

Trong khi đọc jQuery Cookbook (Oreilly) tối qua, tôi đã xem qua một chức năng tạo ra một câu hỏi mà tôi dường như không thể tìm thấy câu trả lời trong cuốn sách, hoặc trực tuyến. Code tôi sử dụng cho câu hỏi này được tìm thấy từ jQuery site và tôi bao gồm nó dưới đây như là một tài liệu tham khảo:

<script> 
    $(document.body).click(function() { 
     $("div").each(function (i) {   //Where does the 'i' come from? 
     if (this.style.color != "blue") { 
      this.style.color = "blue"; 
     } else { 
      this.style.color = ""; 
     } 
     }); 
    }); 
</script> 

Tôi muốn biết nguồn gốc và mục đích của 'i' tham số như tôi không thấy nơi nó đến từ (mã khách hàng) và những gì nó được sử dụng cho? Là một anh chàng Java, tôi sẽ nắm bắt khái niệm dễ dàng hơn nhiều khi tôi quen thuộc với các phương thức hoặc các tham số 'chức năng' trong ngữ cảnh của Java.

Ở đây tôi không thấy mã khách hàng (tôi cho rằng nó nằm trong thư viện) và tôi không thấy nó như thế nào (i) có liên quan trong hàm vì nó không được tham chiếu.

Ai đó trong cộng đồng có thể giải thích rõ ràng về điều này hoặc giới thiệu cho tôi hướng dẫn về điều này không?

Tôi hiểu mục đích của từng chức năng và tham chiếu 'này' để bạn không cần giải thích những điều này trừ khi bạn cảm thấy nó có liên quan đến người xem tương lai của câu hỏi này.

Trả lời

13

Trong trường hợp đó, không cần khai báo số i. Chữ ký của người each method được nêu trong các tài liệu jQuery:

.each(function(index, Element))

Như bạn thấy, phải mất một đối số, và lập luận cho rằng là một chức năng mà có 2 đối số, indexElement.

Trong mã của bạn, i là số nhận dạng cho index, được chuyển đến hàm gọi lại bởi jQuery mỗi khi được gọi (một lần cho mỗi lần lặp). Nó cũng chuyển một đối số thứ hai, nhưng bạn chưa khai báo một mã định danh cho nó để nó chỉ có thể truy cập được thông qua đối tượng arguments.

Bạn có thể thấy chính xác những gì được truyền cho gọi lại bằng cách đăng nhập mà arguments đối tượng:

​$("div").each(function() { //No arguments listed in callback signature... 
    console.log(arguments); //But arguments are still passed 
});​​ 

Dưới đây là một working example những điều trên.

Đây là relevant code from jQuery itself (bình luận thêm):

//... 
each: function(object, callback, args) { 
    //... 

    //Iterate over the matched set of elements 
    for (; i < length;) { 
     /* Call the callback in the context of the element, passing in the 
      index and the element */ 
     if (callback.call(object[ i ], i, object[ i++ ]) === false) { 
      break; 
     } 
    } 
} 
+0

Vì vậy, việc sử dụng chỉ mục bị ẩn trong jQuery và chúng tôi không cần biết nhiều hơn là chúng tôi phải cung cấp nó? – thejartender

+0

Nó sẽ luôn được chuyển đến hàm gọi lại bởi jQuery (do đó sẽ là đối số 'Element'). Nếu bạn muốn sử dụng nó, nó sẽ giúp cho nó một cái tên (như 'i' trong ví dụ của bạn). Tôi đã thêm nguồn jQuery có liên quan, điều này có thể giúp giải thích thêm. –

+0

Tôi sẽ cung cấp cho bạn một phiếu bầu bổ sung cho việc giới thiệu tôi với chức năng nhật ký. Nó sẽ giúp ích rất nhiều :) Cảm ơn – thejartender

2

Khi bạn gọi $().each(), bạn vượt qua nó một chức năng tham khảo. Cách hoạt động của hàm .each() là đối với mỗi phần tử trong đối tượng jQuery, nó gọi hàm mà bạn đã cung cấp với phần tử hiện tại làm ngữ cảnh (tức là bên trong hàm gọi, biến số this là phần tử hiện tại).

Bây giờ, khi jQuery gọi hàm bạn đã cung cấp, nó có thể chuyển vào đối số tùy chọn, giống như khi bạn đang gọi hàm trong mã. Với .each(), bất cứ khi nào nó gọi hàm bạn đã cung cấp, hàm này sẽ chuyển thành hai đối số: một chỉ số thành phần hiện tại.

Đó là nếu jQuery đang kêu gọi nó như:

$('div').each(foo); 

// results in something like 
for(var i=0; i < $('div').length; i++) { 

    // calling the foo function 
    foo(i, $('div')[i]); 

    // this is simplified, of course. 
    // this doesn't take into account the function context, or "this" variable. 
} 

Bạn có thể thấy rằng the official documentation giải thích nó tốt hơn quá.

1

Như đã nói trong API, 'i' là chỉ mục.

Đó có thể là hữu ích nếu bạn muốn tạo sự khác biệt giữa thậm chí và các yếu tố không đồng đều

Giống như:

$(document.body).click(function() { 
    $("div").each(function (i) {   //Where does the 'i' come from? 
    if (i % 2 == 0) { 
     this.style.color = "blue"; 
    } else { 
     this.style.color = ""; 
    } 
    }); 
}); 
1

Các "nguồn gốc" của các thông số này là "cho phép một cách khác nhau từ prototype.js . "
Điều này có ý nghĩa hơn nhiều khi chuyển các tham số theo thứ tự ngược lại vì chỉ số hiếm khi cần.

Hãy xem xét ví dụ này:
gọi hàm & có ý nghĩa nhất?

$('.my-selector').each(modifyNodeA); 
$('.my-selector').each(function(){ 
    // this wrapper anonymous function is cruft 
    modifyNodeB(this); 
}); 
$('.my-selector').each(modifyNodeB); // this one won't work 
$('.my-selector').each(modifyNodeC); 
$('.my-selector').each(function(){ 
    // just using 'this' makes sense here.. it's evident that this is a jQuery closure 
}); 

function modifyNodeA(i, node) { 
    // this one works... but gotta have i in the func signature. 
    // it won't be used and doesn't make contextual sense 
    // can also use 'this', but where the heck did it come from.. it's not evident 
} 

function modifyNodeB(node, i) { 
    // 'i' could/should be an optional 2nd param 
    // this function could function on it's own 
} 

function modifyNodeC() { 
    // gotta use the magic 'this' scope var.. where did it come from? 
    // contextually, it would be nice to have the var passed... it is... as the 2nd param! 
} 

Đơn giản chỉ cần tóm tắt ở đây:

Why I STILL prefer Prototype over jQuery - Section 8 - Other Nit-picks

$.each$().each cả vượt qua lần đầu tiên chỉ số, và sau đó là giá trị để gọi lại. Điều này có nghĩa rằng nếu tôi không cần chỉ mục, tôi không thể chỉ cần để nó ra khỏi khai báo hàm như tôi có thể trong Prototype.