2012-01-04 38 views
8

Tôi mới đến JavaScript, và đang gặp một vấn đề tìm hiểu mã này:Sự hiểu lầm của JavaScript đóng cửa

function addProperty(o) { 
    var value; 

    o["get"] = function() { return value; } 
    o["set"] = function(v) { value = v; } 
} 

var a = {}; 
addProperty(a); 
var b = {}; 
addProperty(b); 

a.set(4); 
b.set(5); 
print("a is " + a.get() + "; b is " + b.get()); 

in này (trong v8/d8) a is 4; b is 5. Nếu tôi nhận xét dòng var value;, tôi nhận được a is 5; b is 5. Đối tượng 'giá trị' ở đâu và tại sao có hai giá trị đó? Cảm ơn.

+0

Tôi không hiểu "tại sao có hai trong số họ "một phần của câu hỏi. Ông có thể làm rõ? – slinzerthegod

+0

Đối tượng 'a' có giá trị liên kết với nó, giữ số nguyên '4' và đối tượng 'b' có giá trị được liên kết với nó, giữ nguyên số nguyên '5'. – EML

Trả lời

12

Biến số value là cục bộ thành addProperty. Lần đầu tiên addProperty được gọi, một value mới được tạo, trên đó cả hai chức năng đều đóng. Lần thứ hai, addProperty được gọi, một giây thứ hai value được tạo trên hai chức năng mới gần.

Loại bỏ var tạo ra một toàn cầuvalue trên đối tượng window được chia sẻ bởi tất cả các chức năng.

Có lẽ bạn có nghĩa là để làm điều này:

function createPropertyMgr() { 
    var value; 
    return function(o) { 
     o["get"] = function() { return value; } 
     o["set"] = function(v) { value = v; } 
    } 
} 

var addProperty = createPropertyMgr(); 

addProperty chức năng mới này đóng cửa hơn một value dù có bao nhiêu lần nó được gọi. Tôi không chắc tôi hiểu trường hợp sử dụng, nhưng điều đó sẽ chứng minh sự khác biệt.

+4

+1 Có một 'giá trị' trong * nguồn *, nhưng hai trong * bộ nhớ *. Điều này có vẻ là sự nhầm lẫn của OP. – pimvdb

+0

Vì vậy, nó tạo ra một bản sao của giá trị var trên mỗi cuộc gọi addProperty. Nhưng, làm thế nào liên kết nó với đối tượng đối số? –

+1

@TomasNarros: giống như vậy. Các tham số chính thức, khai báo hàm và các biến được khai báo với 'var' là tất cả các phần của 'Đối tượng kích hoạt' và có nghĩa là, được sao chép qua để tạo một sự đóng gói từ vựng. – jAndy

1

Khi bạn không khai báo một biến rõ ràng bên trong một hàm, phạm vi của nó được giả định là toàn cục. tức là trong trường hợp thứ hai của bạn, vì bạn chưa khai báo value rõ ràng là cục bộ cho hàm addProperty(), nó được coi là toàn cầu.

Nhưng khi bạn khai báo rõ ràng bên trong một hàm, hàm sẽ trở thành cục bộ cho hàm. Mỗi khi hàm được gọi một bản sao mới của biến cục bộ chức năng được tạo trên ngăn xếp (và quan trọng là nó vẫn ở đó trong ngăn xếp miễn là có tham chiếu đến nó)

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