2012-03-19 35 views
7

Tôi không phải là người dùng JavaScript thực sự tốt nhưng tôi có thể hoàn thành công việc với nó. Tôi không tự hào về mã tôi đã viết bằng JavaScript, vì vậy tôi quyết định thay đổi điều đó. Đây là bước đầu tiên của tôi:Cách phạm vi tốt trong JavaScript

Tôi đang cố gắng tạo thư viện của riêng mình cho một dự án và dưới đây là cấu trúc ban đầu.

window.fooLib = {}; 

(function (foo) { 
    "use strict"; 

    foo.doSomeStuff = function(param1) { 

     console.log(new AccommProperty(param1)); 
    } 

    //some internal function 
    function AccommProperty(nameValue) { 
     var _self = this; 
     _self.name = nameValue; 
    } 

}(fooLib)); 

tôi đã sử dụng ngay lập tức gọi chức năng biểu hiện đây để khởi tạo biến tôi. Trong trường hợp này, nó là fooLib.

Tôi không chắc chắn liệu mình có nên làm một số việc khác để làm cho an toàn hơn cho các số window.fooLib hay không. Tôi có nghĩa là nó có thể được ghi đè bởi bất kỳ mã nào khác sẽ chạy sau mã của tôi nếu tôi hiểu JavaScript chính xác.

Suy nghĩ của bạn là gì?

+0

sử dụng "sử dụng nghiêm ngặt"; và bảo vệ bạn đối tượng, đó là tất cả những gì bạn có thể làm. – Christoph

+0

@Christoph Tôi đã sử dụng '" sử dụng nghiêm ngặt; "ở trên như bạn có thể thấy. Đây có phải là đúng cách và địa điểm sử dụng nó? – tugberk

+2

yep. [xem bài viết của john resig] (http://ejohn.org/blog/ecmascript-5-objects-and-properties/) về cách bảo vệ có thể đạt được hoặc 'Object.freeze (obj)' trên https: // developer .mozilla.org/vi/JavaScript/Tham chiếu/Global_Objects/Object/freeze – Christoph

Trả lời

1

Nếu bạn muốn ngăn ghi đè biến của mình, bạn có thể sử dụng Object.defineProperty() có thể ghi: sai, có thể định cấu hình: sai. Trong trường hợp của bạn:

(function() { 
    "use strict"; 
    var foo = {}; 
    //some internal function 
    function AccommProperty(nameValue) { 
     var _self = this; 
     _self.name = nameValue; 
    } 
    foo.doSomeStuff = function(param1) { 

     console.log(new AccommProperty(param1)); 
    } 
    Object.defineProperty(window, "foolib", {value:foo}); 
}()); 

Tuy nhiên, không có lý do chính đáng cho điều đó. Nó sẽ cần EcamScript 5.1 để làm việc, và không có shims xung quanh; có thể một cái gì đó với getters/setters để ngăn chặn ghi đè với các nhà điều hành =.

Tuy nhiên, cũng không cần phải làm cho thư viện của bạn không thể ghi đè. Chỉ cần không sử dụng mã trên trang web của bạn ghi đè lib. Hoặc có thể ai đó thậm chí muốn ghi đè lên các chức năng của bạn với một chức năng khác, tốt hơn là lib với cùng một giao diện?

Nếu câu hỏi là về thư viện được chia sẻ, với xung đột không gian tên có thể xảy ra với người khác, bạn có thể xem jQuery.noConflict.

0

Mọi đối tượng JavaScript đều có thể được ghi đè lên. Đây là bản chất của JavaScript và không thể thay đổi nó. Vì vậy, bạn không thể làm cho mã của bạn an toàn theo nghĩa đó.

Đối với các chức năng tự hủy: bạn nên sử dụng chúng khi bạn muốn có các biến cục bộ nhưng có thể vi phạm tất cả các chức năng của bạn. Vì vậy, trong trường hợp của bạn AccommProperty là biến số như vậy. Định nghĩa doSomeStuff bên trong phạm vi không có sự khác biệt trừ khi doSomeStuff sẽ sử dụng các biến được định nghĩa bên trong phạm vi.

Vì vậy, khi bạn muốn ẩn biến từ người dùng và/hoặc bạn cần hình cầu và bạn đang lo ngại xung đột tên sử dụng chức năng tự hủy.

+0

cảm ơn! đã thay đổi mã ví dụ của tôi. Bây giờ nó có ý nghĩa hơn tôi nghĩ. – tugberk

-1

Tôi không chắc mình có nên làm một số việc khác để làm cho window.fooLib an toàn hơn hay không. Tôi có nghĩa là nó có thể được ghi đè bởi bất kỳ mã nào khác sẽ chạy sau mã của tôi nếu tôi hiểu JavaScript chính xác.

Thay vào đó, bạn có thể thử biến một biến cục bộ thành window.fooLib. Sử dụng closures and nested functions ai có thể bắt chước một không gian tên nơi bạn có thể đặt tất cả các dữ liệu của bạn thay vì đưa nó vào phạm vi toàn cầu hoặc gắn nó vào window đối tượng:

(function() { 

    // all functions nested in foo() have access to fooLib. 
    fooLib = {} 

    fooLib.doSomeStuff = function(param1) { 
     console.log(param1); 
     console.log(fooLib); 
    } 

    //some internal function 
    function AccommProperty() { 
     console.log(fooLib); 
    } 

}()); 

Xem Javascript Closures: Encapsulating Related Functionality để biết thêm chi tiết.

+0

ok nhưng trong trường hợp này tôi không thể sử dụng 'fooLib' bên ngoài IIFE này và nó sẽ không có ý nghĩa nhiều nếu tôi muốn tạo một thư viện. Hoặc là tôi sai? – tugberk

+0

FooLib của bạn cũng được gắn vào cửa sổ ... Và bạn cần điều đó, để cung cấp truy cập bên ngoài (Đó là ý nghĩa của thư viện ?!) Bất kỳ đối tượng nào trong JS bạn tạo (ES3) đều có thể bị ghi đè nếu bạn không làm việc với ES5 và bảo vệ nó. – Christoph

+0

@tugberk: bạn đặt toàn bộ thư viện của mình vào một hàm giữ trạng thái thư viện dưới dạng biến cục bộ. Tất cả các chức năng thư viện của bạn trở thành hàm lồng nhau. –