2012-02-09 36 views
5

EDITđóng cửa Javascript - sự khác biệt giữa các

Với số câu trả lời nói là những gì "bạn có thể làm cho mọi việc cá nhân!" bên dưới, tôi cũng sẽ thêm phần này vào đầu:

Tôi biết bạn có thể mô phỏng các biến riêng tư trong phạm vi đóng. Đó không phải là những gì tôi yêu cầu. Tôi hỏi, đưa ra hai ví dụ dưới đây, nơi tôi "xuất khẩu" mọi thứ từ việc đóng cửa, sự khác biệt cơ bản giữa hai ví dụ này là gì.

Với hai phương pháp của việc tạo ra đối tượng/phương pháp:

var test = {} 

test = (function(){ 
    var a_method = function(print_me){ 
     return "hello "+print_me; 
    } 

    return {print_me: a_method}; 
})(); 

test.print_me2 = function(print_me2){ 
    return "hello "+print_me2; 
} 

test.print_me('world'); 
>>> returns "hello world" 

test.print_me2('world'); 
>>> returns "hello world" 

Tôi hiểu rằng phương pháp đầu tiên cho phép biến tư nhân (mà như một nhà phát triển python tại trái tim tôi không thực sự quan tâm để sử dụng), nhưng cả hai dường như khá gần gũi với tôi, chỉ có một cái đầu tiên trông "mát mẻ" (như trong tất cả những người javascript lớn dường như đang làm theo cách đó) và cách thứ hai trông rất vượt qua & eacute ;.

Vì vậy, giống như, sự khác biệt là gì?

Tôi đã xem qua các câu hỏi đóng cửa ở đây - hầu hết trong số chúng tập trung vào những gì hoặc tại sao bạn sử dụng chúng; Tôi hiểu tiện ích của họ, tôi chỉ muốn biết tại sao bạn lại làm điều đầu tiên trong lần thứ hai và những lợi ích của nó.

Tôi thích bằng chứng khó hơn phỏng đoán - không tìm kiếm "đây là cách trẻ làm mát" hoặc "tôi nghe rằng mozilla sử dụng bộ nhớ tốt hơn khi bạn sử dụng đóng", nhưng bằng chứng định tính đối với một người là 'tốt hơn' so với người kia.

Trả lời

3

Sự khác biệt giữa các phương thức là trình bao hàm chức năng ẩn danh tạo ra một đóng, nhưng cũng là phương thức đầu tiên thay thế toàn bộ đối tượng trong khi phương thức thứ hai chỉ đặt thuộc tính trong phương thức hiện có.

Có nhiều cách khác nhau để thêm phương thức vào đối tượng. Bạn có thể đặt chúng ở đó khi bạn tạo đối tượng:

var test = { 
    print_me: function(text) { return "hello " + text; } 
}; 

Bạn có thể thêm một phương pháp như một tài sản cho một đối tượng hiện có:

var test = {}; 
test.print_me = function(text) { return "hello " + text; }; 

Bạn có thể tạo một hàm constructor, và thêm các phương pháp để nó mẫu thử nghiệm:

function Test() {} 
Test.prototype.print_me = function(text) { return "hello " + text; }; 
var test = new Test(); 

Khi Javascript có mô hình đối tượng dựa trên nguyên mẫu, phương pháp cuối cùng là phương thức được tạo ra. Các cách khác chỉ có thể vì một thuộc tính đối tượng có thể có một hàm làm giá trị.


Bạn có thể sử dụng một chức năng bao bọc xung quanh bất kỳ mã nơi bạn muốn biến địa phương, vì vậy bạn có thể làm điều đó với cách thứ hai của thiết lập tài sản:

test.print_me2 = (function(){ 

    var method = function(print_me2) { 
    return "hello "+print_me2; 
    } 

    return method; 
})(); 
+0

đó là một câu trả lời tốt hơn nhiều so với trước đây. Và có, tôi hiểu rằng tôi đang đặt đối tượng là kết quả của hàm được thực thi ngay lập tức thay vì đặt thuộc tính của đối tượng được cho phép - giả sử tôi đang cố gắng tạo 'print_me' sẽ là thuộc tính duy nhất trên đối tượng thử nghiệm. Điều gì sẽ là lợi ích của việc làm nó trong một đóng cửa hơn là làm nó như là một nhiệm vụ thẳng? – tkone

+0

@tkone: Lợi ích của việc thực hiện việc đóng cửa chỉ là bạn đóng cửa. Bạn có thể tạo các biến cục bộ, để bạn không gây ô nhiễm không gian tên chung. Tuy nhiên, việc cẩn thận với không gian tên chung là vấn đề lớn hơn nếu bạn đang viết mã hoặc các mã thư viện. Ví dụ, thư viện jQuery lớn chỉ thêm hai tên vào không gian tên chung. – Guffa

+0

ok tuyệt. Đó là chính xác những gì tôi đã cố gắng tìm ra.m tôi biết thêm một tấn tên cho không gian tên toàn cầu là một ý tưởng tồi (do đó sử dụng không gian tên), nhưng chỉ muốn biết nếu mọi người đã đóng cửa vì chúng "nóng" hay nếu họ phục vụ một tiện ích trong một trường hợp như trên. – tkone

2

Trong ví dụ đầu tiên, việc đóng được sử dụng để giữ các biến cục bộ nằm ngoài phạm vi toàn cục.

var thisIsGlobal = 2; 
var test = (function() { 
    var thisIsLocal = 3; 
    return function() { 
    return thisIsLocal; 
    }; 
}()); 

Những gì bạn nhận được là một chức năng test mà khi gọi trở lại các giá trị của biến cục bộ thisIsLocal. Không có cách nào để thay đổi giá trị của biến. Bạn có thể xem nó như một biến riêng.

+1

Tôi thực sự muốn javascript có cách tốt hơn để làm riêng tư ... –

+1

"không có cách nào" không hoàn toàn chính xác. Một số động cơ js (old'ish) cho phép truy cập thuộc tính '.__ parent__' của các hàm, mà infact sẽ cho phép truy cập vào một phạm vi cha mẹ bị đóng. – jAndy

+0

@ JanKuča Tôi hiểu các vấn đề phạm vi ở đây - những gì tôi yêu cầu không liên quan gì đến riêng tư/công khai hoặc mô phỏng, mà là sự khác biệt giữa hai ví dụ - một trong một đóng cửa xuất khẩu MỌI NGƯỜI và một bên ngoài . – tkone

0

Phương pháp đầu tiên bạn hiện tại (một chức năng ẩn danh được thực hiện ngay lập tức) giữ cho chương trình của bạn nằm ngoài phạm vi toàn cầu. Trong phạm vi riêng tư đó, bạn có thể quyết định những thuộc tính nào bạn muốn hiển thị với tư cách là API của mình:

(function(win){ 
    var a, b, c = 1; 

    function init(){ 
    return aa(b); 
    } 

    function exit(){ 
    if(cc()){ 
     return a; 
    } 
    } 

    function aa(){ 
    } 

    function bb(){ 
    } 

    function cc(){ 
    } 

    win.myProgram = {init: init, 
        exit: exit }; 
})(window); 


// We now have access to your API from within the global namespace:  
myProgram.init();  
//etc 
Các vấn đề liên quan