Javascript:范围和保留值

时间:2014-03-22 17:29:04

标签: javascript scope

我有这段代码可视化我正在处理的游戏的磁贴集

for(var i = 0;i<=grid;i++){
    var $row = document.createElement('div');
    $row.className = 'row';

    for (var j = 0; j <= grid; j++) {
        var $tile = document.createElement('div'),
            position = {x:j,y:i};

        $tile.className = 'tile';
        $tile.onclick = function(){
            console.log(position);
            engine.popTile(position);
        }

        $row.appendChild($tile);
    }

    $holder.appendChild($row);
}

但是我遇到了这个问题,在每个磁贴上的位置都是x:15,y:15。现在我假设这是因为我在循环完成他们的业务之后很久就解雇了onclick功能。我的问题是 - 如何在不将其添加到DOM的情况下保留onclick函数的位置数据?

我也尝试在position函数中移动onclick的声明,但没有运气。

2 个答案:

答案 0 :(得分:3)

您可以通过从另一个函数返回函数并将position作为参数传递给顶级函数来保留position的值,如下所示

$tile.onclick = (function(pos) {
    return function() {}
        engine.popTile(pos);
    }
})(position);

现在外部函数在参数position中保留了pos的当前值,并且内部函数也可以使用它。

答案 1 :(得分:1)

这种类型的for循环没有自己的作用域块,因此onClick的闭包始终引用相同的位置变量。在位置前添加var不会创建位置变量的新实例(请参阅变量提升)。

您可以通过执行以下操作来创建范围块:

var $tile = document.createElement('div'),
            position = {x:i,y:j};

for(var i = 0;i<=grid;i++){
    var $row = document.createElement('div');
    $row.className = 'row';

    for (var j = 0; j <= grid; j++) {
        (function(){
            var $tile = document.createElement('div'),
                position = {x:i,y:j};
            $tile.className = 'tile';
            $tile.onclick = function(){
                console.log(position);
                engine.popTile(position);
            }
            $row.appendChild($tile);
        }());
    }

    $holder.appendChild($row);
}

但也许创建createRow和createCell函数会更清晰。