2011-09-12 13 views
0

alert 여기에 오는 이유는 undef입니까?자바 스크립트 : 가변 범위 질문

#!/usr/bin/env perl 
use warnings; 
use 5.014; 
use utf8; 
use Mojolicious::Lite; 
use DBI; 

my $db = 'my_test_db.db'; 
my $table = 'my_test_table'; 
my $dbh = DBI->connect("dbi:SQLite:dbname=$db", '', '', 
      { RaiseError => 1, PrintError => 0, AutoCommit => 1, sqlite_unicode => 1, } 
     ) or die $DBI::errstr; 
$dbh->do("CREATE TEMP TABLE $table (str TEXT, num INTEGER)"); 
my $sth = $dbh->prepare("INSERT INTO $table (str, num) VALUES (?, ?)"); 
$sth->execute('aaa', '111'); 
$sth->execute('bbb', '222'); 
$sth->execute('ccc', '333'); 

get '/eingabe' => sub { 
    my $self = shift; 
    $self->render('eingabe'); 
}; 

get '/search_db/:col' => sub { 
    my $self = shift; 
    my $col = $self->param('col'); 
    my $term = $self->param('term'); 
    my $sth = $dbh->prepare("SELECT DISTINCT $col FROM $table WHERE $col LIKE ?"); 
    $sth->execute($term . '%'); 
    my $ref; 
    while (my $row = $sth->fetchrow_arrayref()) { 
      push @$ref, @$row; 
    } 
    $self->render(json => $ref); 
}; 

app->start; 

__DATA__ 
@@ eingabe.html.ep 
<!DOCTYPE HTML> 
<html> 
<head> 
<meta charset="UTF-8" /> 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.3/jquery.min.js"></script> 
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.js"></script> 
<script type="text/javascript"> 
    $(document).ready(function() { 
     var ids = [ 'str', 'num' ]; 
     for (var i = 0; i < ids.length; i++){ 
      $("#" + ids[i]).autocomplete({ 
       source: function(request, response){ 

        alert(ids[i]); // <--- 

        $.getJSON('/search_db/' + ids[i], request, function(data_from_server){ 
         var suggestions = []; 
         var len = data_from_server.length; 
         for(var i = 0; i < len; i++){ 
          suggestions.push(data_from_server[i]); 
         } 
         response(suggestions); 
        }); 
       } 
      }); 
     } 
    }); 
</script> 
</head> 
<body> 
<form> 
    <table> 
     <tr><td>String:</td><td><input type="text" id="str" name="str"" /></td></tr> 
     <tr><td>Number:</td><td><input type="number" id="num" name="num" /></td></tr> 
    </table><br /> 
    <input type="submit" value="OK"/> 
</form> 
</body> 
</html> 

답변

3

당신이 여기에서 설명하는 것 문제가있는 것 같은데 다음 autocomplete 함수가 호출 될 때 Creating closures in loops: A common mistake이, 당신의 루프가 완료

당신이 alert에 호출 undefined을 얻고있는 이유가되고 있음을 루프 변수 i의 값은 2 즉 ids.length + 1입니다. 따라서 ids[i]ids 배열에 2 개의 요소 만 있기 때문에 존재하지 않는 ids[2]과 같습니다. 나는 무슨 일이 일어나고 있는지 보여주기 위해이 동작에 대한 간단한 데모를 시도했다. 결과를 보려면 브라우저의 콘솔을 열어야한다.

범위를 유지하고 undefined (http://jsfiddle.net/ianoxley/BVa5Q/ 참조)을 없애는 데 도움이되는 추가 클로저를 만드는 경우 이 같은 당신의 코드를 변경하려고하면

잘하면 문제의 제거 얻을 것이다 :이 도움이

$(document).ready(function() { 
    function initAutocomplete(element_id) { 
     $("#" + element_id).autocomplete({ 
      source: function (request, response) { 

       alert(element_id); // <--- 

       $.getJSON('/search_db/' + element_id, request, function (data_from_server) { 
        var suggestions = []; 
        var len = data_from_server.length; 
        for (var i = 0; i < len; i++) { 
         suggestions.push(data_from_server[i]); 
        } 
        response(suggestions); 
       }); 
      } 
     });   
    } 

    var ids = ['str', 'num']; 
    for (var i = 0; i < ids.length; i++) { 
     var current_id = ids[i]; 
     initAutocomplete(current_id); 
    } 
}); 

희망을.

+0

그래, 내가 말하려고하는 것이지만 나는 서둘러야했다. 좋은 설명. –

0

당신은 두 번 i 반복 변수를 정의 : 그것은 다시 $.getJSON 호출 콜백의 내부에 사용됩니다.

다른 이름으로 바꾸려면 j (예)을 사용해야합니다.

는 그렇게 말할 것이다 :

$(document).ready(function() { 
    var ids = [ 'str', 'num' ]; 
    for (var i = 0; i < ids.length; i++){ 
     $("#" + ids[i]).autocomplete({ 
      source: function(request, response){ 

       alert(ids[i]); // <--- 

       $.getJSON('/search_db/' + ids[i], request, function(data_from_server){ 
        var suggestions = []; 
        var len = data_from_server.length; 
        for(var j = 0; j < len; j++){ 
         suggestions.push(data_from_server[j]); 
        } 
        response(suggestions); 
       }); 
      } 
     }); 
    } 
}); 

난이 도움이되기를 바랍니다!

+0

본 적이 없으며 일반적으로 그렇게하지 않을 것입니다. 그러나 JavaScript에서 변수의 범위는 함수입니다. 따라서 내 이론에서 두 번째'var i'는 두 번째'var i'라고 선언 된 함수 외부의 첫 번째'var i '를 망쳐야합니다. –

0

소스 콜백 기능이 범위를 벗어납니다. 이벤트 링크로 함수를 공격하면 for 루프가 완료된 후 이벤트가 트리거 될 때 호출됩니다.

콜백을 사용할 때마다 함수가 필요로하는 모든 것을 항상 전달하거나 객체가 필요로하는 모든 것을 윈도우 객체에 첨부하고 전역으로 되돌려 놓는 것이 좋습니다.