Javascript:变量范围问题

标签 javascript scope

为什么我会在 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>

最佳答案

听起来您遇到了此处解释的问题:Creating closures in loops: A common mistake

您在调用 alert 时收到 undefined 的原因是,当调用 autocomplete 函数时,您的 for 循环已完成执行,意味着循环变量 i 的值为 2,即 ids.length + 1。因此,ids[i]ids[2] 相同,后者不存在,因为 ids 数组中只有 2 个元素。我试图想出一个简单的演示来说明这种行为,以帮助说明发生了什么:http://jsfiddle.net/ianoxley/KwXVs/1/ (您需要打开浏览器的控制台才能查看结果)。

如果您创建了一个额外的闭包,它应该有助于保留您的范围并消除 未定义(请参阅 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);
    }
});

希望这有帮助。

关于Javascript:变量范围问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7388248/

相关文章:

javascript - 函数中未声明的 JavaScript 变量覆盖了使用

javascript - AngularJS 范围作为 HTML 属性值

javascript - 在 JavaScript 中将字节数组转换为二进制

javascript - 定义两个具有相同参数的变量

python - 如何在 Python 中静态(词法)绑定(bind)名称?

SQL - 表别名范围

php - 我什么时候应该使用 'self' 而不是 '$this' ?

javascript - 如何在 angularjs 中使用 json 从 View 更改 Controller

javascript - 通过javascript更改html内容

javascript - Protractor 等待模态对话框