2013-03-09 37 views
8

Làm thế nào jQuery sẽ cho phép xây dựng của nó để hoạt động như một chức năng chấp nhận lý lẽ khi đó constructor của nó cũng đóng vai trò như một chức năng chấp nhận lập luận?jQuery nguyên mẫu và nhà xây dựng chức năng chaining

Tôi là một chút mới để Javascript, vì vậy cho tôi xin lỗi nếu điều này là một câu hỏi noob, (tôi đã xem xét các nguồn nhưng thật khó để cố gắng phân tích).

Dù sao, ví dụ: $(document).ready(<args>); Cả hàm tạo $() và nguyên mẫu ready() hoạt động như một hàm. Làm sao? Bởi vì nếu tôi cố gắng này:

var $ = function(selector) { 
    if(selector == document) { 
     return document; 
    } 
}; 

$.prototype = { 
    constructor: $, 
    ready: function(args) { 
     if(isDomReady) { 
      args.apply(document); 
     } else { 
      window.onload = args; 
     } 
    } 
}; 

var isDomReady = (document.addEventListener || document.readyState == ("complete"|"loaded"|true|4) || document.onreadystatechange()) ? true : false; 

$(document).ready(function() { alert("Wibbles!") }); 

tôi nhận được một lỗi lỗi chưa gặp: Object [đối tượng global] không có phương pháp 'sẵn sàng'

+0

Bạn không chaining các phương pháp bằng cách trả lại 'this' từ 'ready'. –

+1

Tôi biết lý do bạn nhận được thông báo lỗi. $ (Document) chỉ trả về HTMLDocument, mà không có hàm .ready. Nếu $ có thuộc tính "element", đã lưu trữ phần tử tài liệu khi bạn chạy hàm tạo, thì bạn có thể kiểm tra trạng thái sẵn sàng của nó bằng cách truy cập phần tử được lưu trữ trong hàm sẵn sàng. – MattDiamant

+0

@MattDiamant Ahh ... Tôi nghĩ tôi sẽ đọc lại nhận xét đó một vài lần để nghiên cứu. Lol. Nhưng tôi nghĩ tôi hiểu. Cảm ơn. –

Trả lời

8

Bạn biết, điều này khá hấp dẫn tôi. Bạn đã chấp nhận câu trả lời rồi, nhưng hãy để tôi chỉ đăng bài của tôi trong trường hợp nó tỏ ra hữu ích. Có một số fiddle created here

jQuery = function(selector, context) { 
    // The jQuery object is actually just the init constructor 'enhanced' 
    return new jQuery.fn.init(selector, context); 
}; 

jQuery.fn = jQuery.prototype = { 
    constructor: jQuery, 
    context: null, 
    isReady: null, 
    init: function(selector, context) { 
     if (selector === document){ 
      this.context = document; 
      this.selector = document; 
     } 
     console.log(this); 
     return this; 
    }, 
    ready: function(func){ 
     var args = Array.prototype.slice.call(this, arguments), 
      boundReadyFunc = func.bind(this, args.slice(1)); 

     if (this.isReady){ 
      func(); 
     } 
     else { 
      document.addEventListener("DOMContentLoaded", this.onReady.bind(this, func), false); 
     } 
    }, 
    onReady: function(func){ 
     console.log("onready"); 
     this.isReady = true; 
     func.call(this); 
    }, 
}; 

jQuery.fn.init.prototype = jQuery.fn; 
jQuery(document).ready(function(){ 
    alert("Hey, here I am"); 
}); 

Hãy để tôi giải thích cách hoạt động của tính năng này.

Mỗi khi bạn gọi một cái gì đó như $(selector), một cá thể jQuery mới được tạo, với các tùy chọn mà bạn đã cung cấp (xem return new jQuery.fn.init(selector, context););

Để thuận tiện, chúng tôi trưng ra nguyên mẫu jQuery dưới dạng tên toàn cầu khác có tên là jQuery.fn. Để làm cho nó thực sự thể kết nối, các init chức năng phải trả lại một jQuery dụ mới. Đó là lý do tại sao, cuối cùng, chúng tôi một cách rõ ràng xác định rằng nguyên mẫu cho cả jQueryjQuery.init đều giống nhau. Bằng cách này, bạn hiện có thể thực hiện các cuộc gọi chức năng như

$(document).ready(DoSomethingHere) 

Hy vọng điều này sẽ hữu ích.

Ngoài ra, bạn có thể tìm thấy nguồn jQuery trên github. Đó là mô-đun và khá dễ làm theo.

+0

Cảm ơn bạn! Đây là hướng tôi đang tìm kiếm nhiều hơn, nhưng đã muộn một chút, tôi đã vào chuỗi chức năng. Cảm ơn, mặc dù! –

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