2011-12-29 29 views
7

Gần đây tôi đã chơi với javascript, HTML5, tiện ích mở rộng chrome, jQuery và tất cả những thứ tốt đó. Tôi khá ấn tượng cho đến nay với khả năng của javascript, điều duy nhất tôi đấu tranh với là cấu trúc mã của tôi và giữ nó gọn gàng. Trước khi tôi biết điều đó, các chức năng nằm rải rác khắp nơi. Tôi đã luôn luôn thực hiện lập trình của tôi trong một cách hướng đối tượng (C++ và C#), và tôi thấy bản thân mình không thể giữ cho mọi thứ gọn gàng. Nó cảm thấy như tôi luôn luôn kết thúc với một loạt các chức năng util tĩnh, tôi đã 'suy nghĩ' trong C#.Giữ javascript của bạn có cấu trúc và gọn gàng (như một lập trình viên OO)

Tôi đã tìm kiếm một số thông tin về các đối tượng trong javascript, nhưng nó seems to come down to wrapping functions in functions. Đây có phải là cách tốt để cấu trúc mã nguồn của bạn không? Trên bề mặt, có vẻ như một chút tin tặc. Hay có cách nào khác để giữ mọi thứ gọn gàng cho một tư duy OO?

+1

http://addyosmani.com/blog/essential-js-namespacing/ và http://dustindiaz.com/namespace-your-javascript/ là tốt đọc – naveen

+0

"chức năng gói trong các chức năng" không phải là "hackish" ở tất cả. Lập trình viên Haskell làm tất cả các thời gian. –

+0

Tôi đã đọc từ trên lập trình chức năng và đóng cửa và bạn nói đúng. Nó chỉ là một chút suy nghĩ thay đổi từ OOP, vì vậy nó ở cái nhìn đầu tiên nó có vẻ hơi lạ. – diggingforfire

Trả lời

1

Một trong những OOP tốt nhất javascript thư viện ngoài kia là của Google thư viện Đóng http://closure-library.googlecode.com/svn/docs/index.html

Nó có cấu trúc theo một cách mà các lập trình viên OOP sẽ được làm quen với đặc biệt là nếu bạn đến từ một java/C# nền. Có một cái nhìn vào mã nguồn của bất kỳ tập tin và nó sẽ cảm thấy ngay tại nhà như là một lập trình OOP. http://closure-library.googlecode.com/svn/docs/closure_goog_graphics_canvasgraphics.js.source.html

+0

Nguồn thực sự trông rất quen thuộc, và việc sử dụng các bao đóng cho tôi một ý tưởng khá hay về cách làm việc. – diggingforfire

1

Sử dụng một số khung được thiết kế để đáp ứng các yêu cầu tương tự có thể là một ý tưởng hay.

Nhưng có một số điều bạn thực sự nên làm theo để có hiệu quả:

  • nhớ về đóng cửa trong JavaScript và đừng quên về var từ khóa,
  • callbacks sử dụng khi có thể và hợp lý, JavaScript là không đồng bộ bằng cách nature,
2

Một khía cạnh quan trọng cần nhớ về Javascript là nó là ngôn ngữ nguyên mẫu. Các hàm có thể là các đối tượng và bất cứ thứ gì có thể được đặt lên đối tượng, thường ảnh hưởng đến các đối tượng liên quan trong tiến trình. Không có cách nào chính thức để 'mở rộng' một đối tượng vì điều này. Đó là một khái niệm mà tôi vẫn còn có một thời gian khó hiểu.

'Hành vi' của Javascript giống như bất kỳ ngôn ngữ OOP nào khác cho hầu hết các phần, với một số ngoại lệ, cụ thể là các đối tượng mở rộng (http://jsweeneydev.net84.net/blog/Javascript_Prototype.html).

Sau khi nghiên cứu sâu rộng, tôi đã tìm ra một cách rất nhẹ để mô phỏng các đối tượng mở rộng (tôi đang sử dụng nó trong GameAPI). Trường đầu tiên là đối tượng cha, thứ hai là đối tượng mở rộng.

extend : function(SuperFunction, SubFunction) { 

    //'Extends' an object 

    SubFunction.prototype = new SuperFunction(); 
    SubFunction.prototype.constructor = SubFunction; 
}, 

Liên kết này có thể làm sáng tỏ một số vấn đề và quan niệm sai lầm: http://www.coolpage.com/developer/javascript/Correct%20OOP%20for%20Javascript.html

Cá nhân, tôi có xu hướng chống khuôn khổ, và tôi đã không nhìn thấy một khuôn khổ chưa mà không buộc các lập trình viên thay đổi đáng kể phong cách lập trình của họ trong vấn đề này anyway. Thêm sức mạnh cho bạn nếu bạn tìm thấy một, nhưng rất có thể là bạn sẽ không thực sự cần một.

Lời khuyên tốt nhất của tôi là cố gắng thích ứng với phong cách nguyên mẫu của Javascript, thay vì buộc các phương pháp cũ lên đó. Tôi biết nó rất khó; Tôi vẫn đang cố gắng.

Chúc may mắn đào tốt nhất.

2

Tôi thường theo mẫu make-an-anonymous-function-then-call-it. Về cơ bản, bạn tạo một phạm vi bên trong và trả về một đối tượng duy nhất chứa giao diện của bạn. Không có gì khác thoát, bởi vì tất cả đều bị mắc kẹt trong phạm vi chức năng. Dưới đây là một ví dụ sử dụng jQuery:

var FancyWidget = (function($) { 
    // jQuery is passed as an argument, not referred to directly 
    // So it can work with other frameworks that also use $ 

    // Utility functions, constants etc can be written here 
    // they won't escape the enclosing scope unless you say so 
    function message(thing) { 
     alert("Fancy widget says: " + thing); 
    } 

    // Make a simple class encapsulating your widget 
    function FancyWidget(container) { 
     container = $(container); // Wrap the container in a jQuery object 
     this.container = container; // Store it as an attribute 

     var thisObj = this; 
     container.find("#clickme").click(function() { 
      // Inside the event handler, "this" refers to the element 
      // being clicked, not your FancyWidget -- so we need to 
      // refer to thisObj instead 
      thisObj.handleClick(); 
     }); 
    } 

    // Add methods to your widget 
    FancyWidget.prototype.handleClick = function() { 
     this.container.find("#textbox").text("You clicked me!"); 
     message("Hello!"); 
    }; 

    return FancyWidget; // Return your widget class 
         // Note that this is the only thing that escapes; 
         // Everything else is inaccessible 
})(jQuery); 

Bây giờ, sau khi tất cả các mã này thực hiện, bạn kết thúc với một lớp, FancyWidget, sau đó bạn có thể nhanh chóng.

Bạn cũng có thể xác định nhiều lớp theo cách này; thay vì sử dụng return FancyWidget, bạn có thể trả về một đối tượng theo nghĩa đen thay vì:

return { 
     FancyWidget: FancyWidget, 
     Frobnicator: Frobnicator, 

     // Nested namespaces! 
     extra: { 
      thing: thing, 
      blah: blah 
     } 
    }; 
Các vấn đề liên quan