2012-08-27 6 views
5

OK! Trước hết câu hỏi này xuất phát từ một người đàn ông đào sâu quá (và có thể bị lạc mất) trong vũ trụ jQuery.Sự khác biệt về giá trị, nguyên mẫu và thuộc tính

Trong reserch của tôi, tôi đã phát hiện ra mẫu chính của jquery là một cái gì đó như thế này (Nếu chỉnh cần thiết được wellcomed):

(function (window, undefined) { 

    jQuery = function (arg) { 
     // The jQuery object is actually just the init constructor 'enhanced' 
     return new jQuery.fn.init(arg); 
    }, 
    jQuery.fn = jQuery.prototype = { 
     constructor: jQuery, 
     init: function (selector, context, rootjQuery) { 
     // get the selected DOM el. 
     // and returns an array 
     }, 
     method: function() { 
     doSomeThing(); 
     return this; 
     }, 
     method2: function() { 
     doSomeThing(); 
     return this;, 
     method3: function() { 
      doSomeThing(); 
      return this; 
     }; 

     jQuery.fn.init.prototype = jQuery.fn; 

     jQuery.extend = jQuery.fn.extend = function() { 

      //defines the extend method 
     }; 
     // extends the jQuery function and adds some static methods 
     jQuery.extend({ 
      method: function() {} 

     }) 

     }) 

Khi $ khởi jQuery.prototype.init tu và trả về một mảng của các yếu tố. Nhưng tôi không thể hiểu làm thế nào nó thêm phương pháp jQuery như .css hoặc .hide, v.v. vào mảng này.

Tôi nhận được các phương pháp tĩnh. Nhưng không thể có được cách nó trả về và mảng các phần tử với tất cả các phương thức đó.

+0

thanx @adnan cho chỉnh sửa – Lupus

Trả lời

8

Tôi cũng không thích mẫu đó. Họ có một chức năng init, đó là các nhà xây dựng của tất cả các trường jQuery - các jQuery chức năng riêng của mình chỉ là một wrapper quanh mà tạo đối tượng với new:

function jQuery(…) { return new init(…); } 

Sau đó, họ thêm các phương pháp của những trường hợp cho đối tượng init.prototype . Đối tượng này được hiển thị dưới dạng giao diện tại jQuery.fn. Ngoài ra, họ đặt thuộc tính prototype của hàm jQuery cho đối tượng đó - cho những người không sử dụng thuộc tính fn. Bây giờ bạn có

jQuery.prototype = jQuery.fn = […]init.prototype 

Nhưng họ cũng làm hai [lạ] điều:

  • ghi đè constructor tài sản của đối tượng nguyên mẫu, thiết lập nó vào jQuery chức năng
  • lộ init chức năng trên jQuery.fn - nguyên mẫu riêng của nó. Điều này có thể cho phép Extending $.fn.init function, nhưng rất khó hiểu

Tôi nghĩ rằng họ cần/muốn làm tất cả điều này để chống lừa đảo, nhưng mã của họ là một mớ hỗn độn - bắt đầu với đối tượng đó và chỉ định nguyên mẫu init sau đó .

+1

1 vì coi thường mô hình này – Adi

+0

Là viết quá mức hàm tạo cách chúng nhận 'this', nghĩa là giá trị được trả về điểm đến jQuery? ... không có gì là điều kỳ lạ # 2 là ... điều lạ lùng # 1 là gì cho? –

+0

điều này về cơ bản là một hack để nhận được inits 'này' để trông giống như một jQuery' this' –

3

Dễ tiêu hóa hơn nếu bạn cho rằng API là tập hợp các phương thức bên ngoài và hàm jQuery là trình bao bọc.

Đó là cơ bản được xây dựng như thế này:

function a() { return new b();} 
a.prototype.method = function() { return this; } 
function b() {} 
b.prototype = a.prototype; 

Trừ a đó là jQuerybjQuery.prototype.init.

Tôi chắc rằng Resig có lý do để đặt trình tạo api trong nguyên mẫu init, nhưng tôi không thể nhìn thấy chúng.Một vài lạ hơn bên cạnh những người thân Bergi đề cập:

1) Các mô hình đòi hỏi một bản sao tài liệu tham khảo jQuery.fn.init.prototype-jQuery.prototype, mà cho phép một vòng lặp vô tận lạ:

var $body = new $.fn.init.prototype.init.prototype.init.prototype.init('body'); 

2) Mỗi ​​bộ sưu tập jQuery là thực sự là một Ví dụ của jQuery.fn.init, nhưng vì chúng tham chiếu cùng một đối tượng mẫu thử nghiệm, nên chúng tôi khuyên "chúng ta" nghĩ rằng bộ sưu tập là một thể hiện của jQuery. Bạn có thể làm phù thủy cùng như thế này:

function a(){} 
function b(){} 
a.prototype = b.prototype; 
console.log(new b instanceof a); // true 
console.log(new a instanceof b); // true 

Sidenote: Tôi có cá nhân sử dụng các mô hình xây dựng sau với kết quả tương tự mà không có sự weirdness:

var a = function(arg) { 
    if (!(this instanceof a)) { 
     return new a(arg); 
    } 
}; 
a.prototype.method = function(){ return this; };