2012-10-17 12 views
18

Javascript nét đóng cửa nói:Biến số miễn phí là gì?

A "đóng cửa" là một biểu hiện (thường là một chức năng) có thể có miễn phí biến cùng với một môi trường mà liên kết với các biến (rằng "đóng cửa" các biểu hiện).

Một số người có thể giải thích cho tôi khái niệm về biến miễn phí không? Khái niệm này có phải là Javascript cụ thể hoặc áp dụng cho các ngôn ngữ khác không?

+3

Biến miễn phí chỉ đơn giản là một biến không được khai báo bên trong một hàm đã cho, nhưng được sử dụng bên trong nó. –

Trả lời

22

Biến miễn phí chỉ đơn giản là các biến không được khai báo cục bộ hoặc không được chuyển làm tham số.

Source :

Trong lập trình máy tính, biến miễn phí hạn đề cập đến biến được sử dụng trong một hàm mà không phải là các biến cục bộ hay các thông số đó chức năng. 1 Biến không phải là biến cục bộ thường là một từ đồng nghĩa trong ngữ cảnh này.

Trong đóng javascript, đó chỉ đơn giản là các biến mà hàm nhận (đọc và ghi) trong phạm vi bao quanh nơi được khai báo là đóng hoặc trong phạm vi gốc.

Nhìn vào ví dụ thế giới thực này:

Gol.prototype._ensureInit = function() { 
    ... 
    var _this = this; 
    var setDim = function() { 
     _this.w = _this.canvas.clientWidth; 
     _this.h = _this.canvas.clientHeight; 
     _this.canvas.width = _this.w; 
     _this.canvas.height = _this.h; 
     _this.dimChanged = true; 
     _this.draw(); 
    }; 
    setDim(); 
    window.addEventListener('resize', setDim); 
    ... 
}; 

Trong ví dụ này một điểm đóng cửa từ setDim chức năng đối với các biến _this khai báo trong phạm vi kèm theo (các _ensureInit chức năng). Biến này không được khai báo trong setDim cũng không được chuyển. Đó là "biến miễn phí".

Lưu ý rằng _this không trở thành biến số của hàm setDim: một hàm khác được khai báo trong cùng phạm vi sẽ chia sẻ cùng một biến.

+0

"Trong ngữ cảnh này, đó chỉ đơn giản là các biến mà hàm nhận (đọc và ghi) trong phạm vi bao quanh, nơi được khai báo là đóng." không chắc bạn có ý gì? Bạn có thể giải thích với một ví dụ, có thể được? – Geek

+0

@Geek Tôi đã thêm một ví dụ về thế giới thực –

0

Như một ví dụ:

var myModule = (function(){ 
    var moduleVar; // closure variable 

    return function(){ 
    // actual function 
    } 
})(); 

biến được xác định có một biến đóng cửa. nó có thể được sử dụng trên tất cả các bản thân nó nhưng không phải là một phần của không gian tên chung.

0

Một "bản dịch miễn phí" có thể là: "out of scope" - variables.

Vì ECMAscript sử dụng phạm vi từ vựng, biến miễn phí là biến được xác định trong phạm vi gốc và được tìm kiếm bằng tìm kiếm chuỗi phạm vi.

(function _outerScope() { 
    var foo = 42; 

    (function _innerScope() { 
     var bar = 100; 

     console.log(foo + bar); // 142 
    }()); 
}()); 

Trong ví dụ trên, foo là một miễn phí biến trong bối cảnh của _innerScope. nó trở nên rất rõ ràng nếu chúng ta có một cái nhìn nhanh chóng vào các khái niệm cơ bản của ECMAscript.

Một Context được liên kết với một đối tượng Hoạt (trong ES3), tương ứng một từ vựng Môi trường Ghi (trong ES5), trong đó có những câu như: function declarations, variables declared with varformal paramters, cũng như một tham chiếu đến tất cả Đối tượng kích hoạt gốc/Môi trường thực tế. Nếu cần phải truy cập biến, công cụ ECMAscript đầu tiên sẽ xem xét AOs/LEs từ chính hiện tại Ngữ cảnh chính nó; nếu không tìm thấy nó ở đó, nó sẽ nhìn vào phụ huynh AO 's/LE' s.

Vì bất kỳ Context lưu trữ dữ liệu này trong một cấu trúc mảng giống như (đừng quên chúng ta đang nói về mức độ thực hiện ở đây, không Javascript chính nó), chúng ta đang nói về Lexical Scope, bởi vì chúng tôi tìm kiếm thông qua tất cả parent Contexts theo thứ tự.