javascript中的未定义变量

时间:2015-07-07 05:08:46

标签: javascript scope

我很难理解javascript中某些变量的范围。 在下面的代码中 - 我想进行一个ajax调用,并在我的结果上循环创建一些html元素,这些元素稍后会被填充...也在原始循环中我想填充一个我将在稍后使用的数组。 / p>

当我第一次写它时,我在.done函数中创建了数组,但是在稍后测试.length(things_ids.length)时我得到了一个未定义的。所以我将它移动到调用函数,但是当我稍后再使用它时它仍然是未定义的。

...
var things_ids = [];

$( '.filter' ).click( function() {

    $.ajax({
        method: 'POST',
        url: 'list.html',
        data: { ... },
        dataType: 'json',
        cache: false
    })
   .fail( function( jqXHR ) {

        $( '#msg' ).append( '...fail msg...' + jqXHR.responseText + ' ' + jqXHR.statusText );

    })
    .done( function ( data ) {

        // html back to user
        var divs = '';

        if ( data['DATA'].length ) {

            for ( var i = 0; i < data['DATA'].length; i++ ) {

                divs += '<div class="header" >' + data['DATA'][i][1] + ' <span class="toggle-thing" >( show )</span></div>\
                <div class="container" id="thing_' + data['DATA'][i][0] + '" ></div>';
                things_ids.push( data['DATA'][i][0] );

            }

        } else {

            divs = '<div>We have no data.</div>';

        }

        // populate the select
        $( '#things_container' ).html( divs ).slideDown( 3000 ).fadeIn( 1000 );

    });


    // here's where it goes wonky for me

    alert( 'thing id : ' + things_ids ); // this show nothing

    // here i want to load data to the newly created divs
    if ( things_ids.length ) {

        for ( var t = 0; t < things_ids.length; t++ ) {

            alert( 'thing id : ' + things_ids[g] );

            $( '#thing_' + things_ids[t] ).hide(); // start by hiding the div - toggle later....

            // spinner
            $( '#thing_' + things_ids[t] ).html( '<img src="spinner.gif" alt="data loading" />' );
                // content

            $( '#thing_' + things_ids[t] ).load( '/things', function( response, status, xhr ) {

                if ( status == 'error' ) {

                    var msg = 'Sorry but there was an error loading the thing: ';
                    $( '#thing_' + things_ids[t] ).html( msg + xhr.status + ' ' + xhr.statusText );

                }

            });

        }

    }

});

2 个答案:

答案 0 :(得分:1)

Javascript是异步的。在你的情况下,你试图检查ajax调用后的长度。但是呼叫还没有返回值。你可以做的是把你的if条件放在一个函数中,在完成的回调中调用这个函数并将数组传递给它。

    $( '.filter' ).click( function() {

        $.ajax({
            method: 'POST',
            url: 'list.html',
            data: { ... },
            dataType: 'json',
            cache: false
        })
       .fail( function( jqXHR ) {

            $( '#msg' ).append( '...fail msg...' + jqXHR.responseText + ' ' + jqXHR.statusText );

        })
        .done( function ( data ) {

            // html back to user
            var divs = '';
            var things_ids = [];

            if ( data['DATA'].length ) {

                for ( var i = 0; i < data['DATA'].length; i++ ) {

                    divs += '<div class="header" >' + data['DATA'][i][1] + ' <span class="toggle-thing" >( show )</span></div>\
                    <div class="container" id="thing_' + data['DATA'][i][0] + '" ></div>';
                    things_ids.push( data['DATA'][i][0] );

                }

            } else {

                divs = '<div>We have no data.</div>';

            }


            // populate the select
            $( '#things_container' ).html( divs ).slideDown( 3000 ).fadeIn( 1000 );
            makeACallToThis( things_ids );

        });



    });


function makeACallToThis( things_ids ){
    // here's where it goes wonky for me

    alert( 'thing id : ' + things_ids ); // this show nothing

    // here i want to load data to the newly created divs
    if ( things_ids.length ) {

        for ( var t = 0; t < things_ids.length; t++ ) {

            alert( 'thing id : ' + things_ids[g] );

            $( '#thing_' + things_ids[t] ).hide(); // start by hiding the div - toggle later....

            // spinner
            $( '#thing_' + things_ids[t] ).html( '<img src="spinner.gif" alt="data loading" />' );
                // content

            $( '#thing_' + things_ids[t] ).load( '/things', function( response, status, xhr ) {

                if ( status == 'error' ) {

                    var msg = 'Sorry but there was an error loading the thing: ';
                    $( '#thing_' + things_ids[t] ).html( msg + xhr.status + ' ' + xhr.statusText );

                }

            });

        }

    }

}

答案 1 :(得分:-1)

在ajax的定义中添加async: false。这将保留代码的其余部分的执行,直到你得到ajax的响应。 (不推荐)

$.ajax({
    method: 'POST',
    url: 'list.html',
    data: { ... },
    dataType: 'json',
    cache: false,
    async: false
})

如果您不想创建异步ajax,请在提醒后添加代码(&#39; thing id:&#39; + things_ids); //这在ajax的完成函数结束时没有显示任何内容 -

修改

没有异步,因为它可以冻结浏览器以获取长请求,您可以使用此

...
var things_ids = [];

$( '.filter' ).click( function() {

    $.ajax({
        method: 'POST',
        url: 'list.html',
        data: { ... },
        dataType: 'json',
        cache: false
    })
   .fail( function( jqXHR ) {

        $( '#msg' ).append( '...fail msg...' + jqXHR.responseText + ' ' + jqXHR.statusText );

    })
    .done( function ( data ) {

        // html back to user
        var divs = '';

        if ( data['DATA'].length ) {

            for ( var i = 0; i < data['DATA'].length; i++ ) {

                divs += '<div class="header" >' + data['DATA'][i][1] + ' <span class="toggle-thing" >( show )</span></div>\
                <div class="container" id="thing_' + data['DATA'][i][0] + '" ></div>';
                things_ids.push( data['DATA'][i][0] );

            }

        } else {

            divs = '<div>We have no data.</div>';

        }

        // populate the select
        $( '#things_container' ).html( divs ).slideDown( 3000 ).fadeIn( 1000 );

        // here's where it goes wonky for me

        alert( 'thing id : ' + things_ids ); // this show nothing

        // here i want to load data to the newly created divs
        if ( things_ids.length ) {

            for ( var t = 0; t < things_ids.length; t++ ) {

                alert( 'thing id : ' + things_ids[g] );

                $( '#thing_' + things_ids[t] ).hide(); // start by hiding the div - toggle later....

                // spinner
                $( '#thing_' + things_ids[t] ).html( '<img src="spinner.gif" alt="data loading" />' );
                    // content

                $( '#thing_' + things_ids[t] ).load( '/things', function( response, status, xhr ) {

                    if ( status == 'error' ) {

                        var msg = 'Sorry but there was an error loading the thing: ';
                        $( '#thing_' + things_ids[t] ).html( msg + xhr.status + ' ' + xhr.statusText );

                    }

                });

            }

        }

    });

});