那么回调函数中的变量范围呢?

时间:2013-08-06 16:18:44

标签: javascript jquery callback scope

如果我在回调函数中有回调函数,则无法到达第一个回调中声明的变量。

参见示例(使用一些jquery):

my fiddle

这是为什么?

我做错了什么!?

我在下面使用它:

$('<div/>').html(data).find('load').each(function(id, deze) {

        var method = $(deze).attr("method");
        var animate = $(deze).attr("animate");
        var locatie = $(deze).attr("id");
        var html = $(deze).html();

        if(!method){
            method = 'overide';
        }

        if(!locatie){
            error('A002','No loadloc');
        }

        if(!html){
            html = '';
        }

        if(!animate){
            animate = false;
        }
        else if(animate == 'fade'){
            var effectout = 'fade';
            var timeout = 100;
            var optionsout = {
                easing: 'swing'
            };

            var effectin = 'fade';
            var timein = 600;
            var optionsin = {
                easing: 'swing'
            };
        }
        else{
            animate = false;
            error('A006','Animation: "' + animate + '" does not exist');
        }

            //here I make callback or direct function call
        if(animate){
            $('#' + locatie).hide(effectout, optionsout, timeout, load());
        }
        else{
            load();
        }

    function load(){
        console.log('hallo');
        console.log(html);
        if(method == 'overide'){
            $('#' + locatie).html(html);
        }
        else if(method == 'tablerow'){
            var html = $('tr', deze).html();
            $('#' + locatie).html(html);
        }
        else if(method == 'append'){
            $('#' + locatie).append(html);
        }
        else if(method == 'prepend'){
            $('#' + locatie).prepend(html);
        }
        else{
            error('A007','load method: "' + method + '" does not exist');
        }

        if(animate){
            $('#' + locatie).show(effectin, optionsin, timein);
        }
    }

    });

3 个答案:

答案 0 :(得分:3)

  

为什么会这样?

不是。您只需访问something,它就在您发布的load函数的范围内。

  

我做错了什么!?

你没有将load函数本身作为回调传递,但它的结果是 - 你立即调用它(没有参数)。你想要

$('#' + locatie).hide(effectout, optionsout, timeout, load);
//                                                        ^^
//It seems I can't reach html and other variables here
console.log(this.html);

这不是变量,这是this的属性(并且this keyword指向不同调用中的不同内容)。你想要的是一个简单的变量:

console.log(html);

this.locatie和其他人的相同故事。

答案 1 :(得分:1)

我改变了你的代码,我相信这就是你想要做的事情:

http://jsfiddle.net/smerny/2M6k3/

var anothercallbackfunctiontriggerthing = function(cb) {
    cb();
}

$('.something').each(function(id, value) {
        var something = 'something';
        var load = function(){
                    // can't reach something here
                    console.log(something);
        }
        anothercallbackfunctiontriggerthing(load);
});

由于load()没有返回任何内容,我认为您希望将其作为回调(load)传递,然后从anothercallbackfunctiontriggerthing内调用它。上面的代码会为每个.something打印“内容”。

答案 2 :(得分:0)

它不起作用的原因是因为关键字thisload()的上下文中改变了含义,因为您使用function load()定义了一个函数。有几种方法来解决这个问题;这是一个:

在:

if(animate){
            $('#' + locatie).hide(effectout, optionsout, timeout, load());
        }
        else{
            load();
        }

使用

var load = (function(el) {
    return function() {
        console.log('hallo');
                //It seems I can't reach html and other variables here
        console.log(el.html);
        if(method == 'overide'){
            $('#' + el.locatie).html(el.html);
        }
        else if(method == 'tablerow'){
            var html = $('tr', deze).html();
            $('#' + el.locatie).html(el.html);
        }
        else if(method == 'append'){
            $('#' + el.locatie).append(el.html);
        }
        else if(method == 'prepend'){
            $('#' + el.locatie).prepend(el.html);
        }
        else{
            error('A007','load method: "' + el.method + '" does not exist');
        }

        if(el.animate){
            $('#' + el.locatie).show(el.effectin, el.optionsin, el.timein);
        }
    };
})(this);

我在那里做的是用this更改对el的所有引用。然后我使用以下格式将this注入el

load = ( function(el) {  return yourFunction() {...}; })(this);

让我知道这是否有意义,如果它适合你:)