2013-08-26 37 views
5

Ít nhất là những gì tôi nghĩ rằng nó sẽ xảy ra trong trường hợp này:JavaScript setTimeout không thể truy cập biến chức năng

function MyFunc() { 
    var people = Array({name: 'Alex', age: 25}, {name: 'Ellen', age: 43}); 
    for (var i=0; i<people.length; i++) { 
     setTimeout(function() { ShowIt(people[i].name) }, 1000); // !!! 
    } 
} 

function ShowIt(name) { 
    alert(name); 
} 

tôi nhận được lỗi này Uncaught TypeError: Cannot read property 'name' of undefined, vì vậy nó trông giống như bên trong hàm setTimeout listener biến people không phải là có thể truy cập. Tại sao và làm thế nào tôi có thể sửa chữa nó?

+0

Đây là lỗi rất phổ biến, hãy xem câu hỏi này: http://stackoverflow.com/questions/5226285/settimeout-in-a-for-loop-and-pass-i-as-value –

+1

Không, điều đó có nghĩa là rằng 'người [i]' không được định nghĩa. Nếu 'người' không nằm trong phạm vi, bạn sẽ nhận được một cái gì đó giống như' Tham chiếu không bắt buộc: mọi người không được định nghĩa'. –

Trả lời

21

Thực tế, mọi người mảng là ok. Điều gì xảy ra là tôi thực sự là 2 và không có phần tử thứ ba trong mảng. Đó là lý do tại sao bạn nhận được lỗi này. Dưới đây là giải pháp:

function MyFunc() { 
    var people = Array({name: 'Alex', age: 25}, {name: 'Ellen', age: 43}); 
    for (var i=0; i<people.length; i++) { 
     (function(i) { 
      setTimeout(function() {    
       ShowIt(people[i].name) 
      }, 1000); 
     })(i); 
    } 
} 

function ShowIt(name) { 
    console.log(name); 
} 

MyFunc(); 

đây là một jsfiddle http://jsfiddle.net/krasimir/XDfLu/2/

Câu trả lời dài: khi bạn sử dụng setTimeout bạn đang đi qua một chức năng để nó. Chức năng đó được gọi trong tương lai và những thứ bạn thực hiện ở đó cũng được thực hiện trong tương lai. Tại thời điểm đó (một trong tương lai) của bạn tôi không còn 0 hoặc 1. Nó thực sự là 2 vì vòng lặp của bạn đã kết thúc. Giải pháp được cung cấp sử dụng đóng cửa bổ sung để tạo thêm một phạm vi/ngữ cảnh. Và một khi hàm được truyền tới setTimeout được gọi là nó sẽ tìm một biến i. Không có một điều như vậy trong phạm vi của nó, vì vậy nó đi một cấp lên. Và có giá trị thực tế mà chúng ta cần.

+0

Chăm sóc để giải thích giải pháp? Nó là gì và tại sao nó giải quyết vấn đề? –

+0

Trả lời chỉnh sửa. (Tôi không chắc chắn rằng tôi đã giải thích nó đủ). – Krasimir

+0

Gần. Mặc dù bạn đã thêm một cuộc gọi chức năng, nó không quan trọng cho dù chức năng là một đóng cửa hay không. Điều quan trọng duy nhất là hàm được thực hiện và tạo ra một phạm vi mới thông qua đó. –

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