2008-10-09 25 views
9

Tôi tò mò muốn biết liệu có bất kỳ thực tiễn tốt nhất nào liên quan đến JQuery khi xây dựng các khối mã được đóng gói hay không.Thiết kế JavaScript JQuery: Tự thực hiện chức năng hoặc đối tượng văn học?

Nói chung, khi tôi xây dựng một trang, tôi muốn đóng gói các chức năng được sử dụng trong trang đó bên trong một đối tượng. Điều này cho phép tôi đóng gói một số khi xây dựng các ứng dụng. Không có gì tôi ghét hơn là nhìn thấy một tệp JavaScript với một bó của số này

function doSomethingOnlyRelevantOnThisPage() { 
    // do some stuff 
} 

Tôi làm cho thiết kế lộn xộn và không thực sự đóng gói chức năng độc đáo.

Thường trong nhiều khuôn khổ, có một tiêu chuẩn được sử dụng để thực hiện đóng gói này.

Trong Mootools họ ủng hộ các Object Notation Literal:

var Site = {   
    // properties and methods 
} 

Trong YUI họ ủng hộ sự tự Thực hiện ký hiệu Chức năng:

(function() { // properties and methods })() 

Những điều tốt đẹp về ví dụ thứ hai là một đóng cửa được tạo ra , do đó cho phép bạn xác định các thuộc tính và phương thức riêng.

Câu hỏi của tôi là: Có bất kỳ người đam mê JQuery nào có bất kỳ phương pháp hay nhất nào để tạo các cấu trúc được đóng gói gọn gàng này không? Lý do đằng sau việc sử dụng của họ là gì?

Trả lời

9

Vì tôi đã làm việc với jQuery trong một thời gian, tôi đã quyết định một mẫu chuẩn hoạt động tốt cho tôi.

Đó là sự kết hợp của mẫu mô-đun YUI với một chút mẫu plugin jQuery được trộn lẫn. . Chúng tôi đã kết thúc bằng cách sử dụng mô hình đóng cửa tự thực hiện.Điều này có lợi trong một vài cách sau:

  1. Nó giữ mã để tối thiểu
  2. Nó thực thi tách hành vi từ trình bày
  3. Nó cung cấp một kết thúc, giúp ngăn chặn các cuộc xung đột đặt tên

Đây là những gì có vẻ như:

;(function($) {   
    var myPrivateFunction = function() { 
    }; 

    var init = function() { 
     myPrivateFunction(); 
    }; 

    $(init); 
})(jQuery); 

Chúng tôi nhận ra rằng việc chỉ định kết quả thực hiện chức năng, tương tự như mẫu mô-đun YUI, cho thấy mã có khả năng được gọi từ bên trong mã trình bày. Chúng tôi muốn ngăn chặn điều này, vì vậy mô hình này phù hợp.

Tất nhiên chúng tôi có thể đã viết phương thức init nội tuyến, không xác định biến cho hàm. Chúng tôi đã đồng ý rằng việc xác định rõ ràng hàm init đã làm cho mã rõ ràng hơn cho người đọc.

Điều gì sẽ xảy ra nếu chúng tôi muốn chia sẻ các chức năng giữa các trang/tệp js bên ngoài? Chúng ta chỉ cần móc vào cơ chế hiện có mà jQuery cung cấp để mở rộng chính đối tượng jQuery - hàm mở rộng.

Nếu các hàm tĩnh, chúng tôi sử dụng $ .extend và nếu chúng hoạt động trên một tập hợp gói, chúng tôi sử dụng hàm $ .fn.extend.

Hy vọng điều này sẽ giúp ai đó.

+1

Tôi tiếp tục nhìn thấy mô hình này, nhưng tôi khao khát một ví dụ đầy đủ hơn - Tôi đã có một trang với một vài yếu tố tương tác riêng biệt và khá có liên quan mà logic nên được đóng gói ngoài nhau. Bất kỳ đề xuất nào về tổ chức mã trong loại tình huống đó? Sử dụng $ .fn.extend cho mỗi phần giao diện người dùng khác nhau có vẻ phản trực giác. –

+0

Tôi chắc chắn sẽ không ủng hộ bằng cách mở rộng chức năng jquery trừ khi bạn đang viết một plugin - vì vậy một cái gì đó có thể tái sử dụng trong nhiều trang. Tôi sẽ, trong trường hợp của bạn, phá vỡ chức năng của tôi lên thành các phần riêng biệt của nó, tạo ra một chức năng tự thực hiện để chứa logic đó trong đóng cửa riêng của mình. Bất kỳ mã chia sẻ nào cũng có thể được gắn vào chính jQuery thông qua $ .extend, cho phép bạn có các hàm trợ giúp không yêu cầu ngữ cảnh của một phần tử hoạt động. –

+0

Bài viết rất hay về Biểu thức hàm ngay lập tức (IIFE) http://benalman.com/news/2010/11/immediately-invoked-function-expression/ – stormwild

1

tôi thường làm theo mô hình nguyên mẫu:

MyFunction = function(param1, param2) 
{ 
    this.property1 = param1; 
    // etc. 
} 

MyFunction.prototype = 
{ 
    memberOne: function(param1) 
    { 
     // ... 
    }, 

    memberTwo: function(param2) 
    { 
    } 
} 

Bạn nhận được một cái gì đó một "nhà xây dựng" (chức năng chính nó) và đóng gói "phương pháp" và "lĩnh vực".

Đó là dễ dàng hơn cho những người đang sử dụng các ngôn ngữ OO dựa trên lớp :)

+0

Nhưng điều này chỉ hữu ích nếu bạn có kế hoạch đóng gói trạng thái trong các đối tượng. Bạn sẽ phải gọi mới trên các đối tượng này để tạo các thể hiện. Trong trường hợp của tôi, họ sẽ cư xử giống như một lớp tĩnh trong thuật ngữ OO. –

+0

Đúng, đúng ... trong trường hợp này, tôi muốn tự thực hiện các chức năng ẩn danh. –

3

tôi sử dụng YUI và jQuery khi đang phát triển (YUI widget và một vài chức năng tiện nghi, selectors jQuery và javascript "mở rộng"), và nói chung javascript mẫu tôi sử dụng là:

/*global YAHOO, $ */ 

// Create the public-scope accessable namespace for this page 
YAHOO.namespace('Project'); 

YAHOO.Project.page = function() { 
    // Private members 

    var self = {}; 

    // Public members 
    var pub = {}; 

    pub.init = function() { 

    }; 

    return pub; 
}(); 

// When the DOM is loaded, initialize this module 
$(document).ready(YAHOO.Project.page.init); 

Bây giờ rõ ràng, bạn có thể loại bỏ YAHOO.namespace() gọi nếu bạn không muốn sử dụng YUI, nhưng đó là phác thảo cơ bản. Nó sử dụng ký hiệu chữ của đối tượng, nhưng cũng cho phép bạn định nghĩa các thuộc tính và phương thức riêng.

Chỉ cần nhớ rằng khi gọi cho các thành viên riêng tư hoặc tham chiếu các biến riêng tư để tham chiếu chúng dưới dạng self.funcName(). Bạn có thể định nghĩa chúng bên ngoài đối tượng self, nhưng sau đó bạn nhận được một sự lộn xộn ở khắp mọi nơi trong đối tượng của bạn, nơi bạn đang cố gắng tìm ra nếu size_of() là một phương pháp riêng hoặc được xác định trên toàn cầu ở một nơi khác.

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