2015-07-11 16 views
6

tôi có chức năng sau makeStopwatch mà tôi đang cố gắng để làm việc thông qua để hiểu rõ hơn về việc đóng cửa javascript:Làm thế nào để truy cập các biến trong phạm vi khác bên trong một hàm bằng cách sử dụng đóng trong javascript?

var makeStopwatch = function() { 
    var elapsed = 0; 
    var stopwatch = function() { 
    return elapsed; 
    }; 
    var increase = function() { 
    elapsed++; 
    }; 

    setInterval(increase, 1000); 
    return stopwatch; 
}; 

var stopwatch1 = makeStopwatch(); 
var stopwatch2 = makeStopwatch(); 

console.log(stopwatch1()); 
console.log(stopwatch2()); 

Khi tôi console.log các cuộc gọi đến và stopwatch1stopwatch2 tôi nhận được 0 trở mỗi lần tương ứng.

Khi tôi hiểu chức năng dự định của makeStopwatch biến số elapsed sẽ là 0 nếu được trả về bởi hàm bên trong stopwatch. Hàm bên trong increase tăng biến elapsed. Sau đó, setInterval gọi increase sau khi trì hoãn 1 giây. Cuối cùng, stopwatch được trả lại lần này với giá trị được cập nhật dự kiến ​​là 1.

Nhưng điều này không hiệu quả vì bên trong makeStopwatch, các hàm bên trong stopwatch, increasesetInterval đều nằm trong phạm vi độc lập của nhau?

Làm thế nào tôi có thể sửa đổi này để làm việc như tôi hiểu nó để elapsed được tăng lên và giá trị đó là đóng cửa trên và lưu để khi tôi gán makeStopwatch để biến stopwatch1 và gọi stopwatch1 giá trị cập nhật được trả lại?

+0

Mã của bạn đang hoạt động. Ngoài ra, CodeSchool? (Tôi đặt mã của bạn chính xác như bạn có nó vào giao diện điều khiển. Chạy 'console.log (stopwatch1())' nhiều lần.) – ChadF

+2

Mã được đăng sẽ luôn ghi nhật ký 0 cho cả hai console.log sẽ xuất hiện trong vòng 1 giây của đồng hồ bấm giờ được tạo. Hãy thử gói hai dòng dưới cùng trong một 'setTimeout (console.log (stopwatch1()), 2000);' 'setTimeout (console.log (stopwatch2()), 4000);' ví dụ để thấy rằng các đồng hồ bấm giờ thực sự là " chạy " –

+0

Tôi đoán tôi đang bối rối vì nhìn vào thân của hàm' tăng' và cách 'elapsed' được tăng lên, cũng như nhận thức được nhận thức của tôi về đồng hồ bấm giờ trong thế giới thực, tôi mong đợi console.logs cho thấy đồng hồ bấm giờ thực sự đang đếm ngược. – phizzy

Trả lời

3
var makeStopwatch = function() { 
    var elapsed = 0; 

    // THIS stopwatch function is referenced later 
    var stopwatch = function() { 
    return elapsed; 
    }; 

    var increase = function() { 
    elapsed++; 
    }; 
    // This setInterval will continue running and calling the increase function. 
    // we do not maintain access to it. 
    setInterval(increase, 1000); 

    // THIS returns the stopwatch function reference earlier. The only way 
    // we can interact with the closure variables are through this function. 
    return stopwatch; 
}; 

var stopwatch1 = makeStopwatch(); 
// This runs the makeStopwatch function. That function *RETURNS* the 
// inner stopwatch function that I emphasized above. 

console.log(stopwatch1()); 
// stopwatch1 is a reference to the inner stopwatch function. We no longer 
// have access to the elapsed variable or the function increase. However 
// the `setInterval` that is calling `increase` is still running. So every 
// 1000ms (1 second) we increment elapsed by 1. 

Vì vậy, nếu đã đặt tất cả các mã trên vào giao diện điều khiển, và sau đó gọi console.log(stopwatch1()) thỉnh thoảng, nó sẽ console.log số giây kể từ khi chúng tôi tạo ra đồng hồ bấm giờ.

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