访问匿名函数之外的变量

时间:2014-03-06 20:32:30

标签: javascript jquery node.js node-webkit

我知道这可能是重复但我无法弄清楚如何做到(相信我,我已经搜索过,我试图摆弄代码)。我有以下代码,它构建了一个可以拖放到应用程序中的文件表。

function CreateTrackTable (data, length) {

    var fs = require('fs'),
        mm = require('musicmetadata'),
        i  = 0;

    for (i; i < length; ++i) { 

        var mimeType = data.dataTransfer.files[i].type;

        if (mimeType == "audio/mp3" || mimeType == "audio/x-m4a"){

                FilePath = data.dataTransfer.files[i].path;
                var parser = mm(fs.createReadStream(FilePath));

            parser.on('metadata',  function (result) {

                if (result.picture.length == 0) {
                    $("#track-table").append('<tr path="'+ FilePath +'"><td></td></tr>');
                }else{
                    var picture = base64ArrayBuffer(result.picture[0].data);
                    $("#track-table").append('<tr path="'+ FilePath +'"><td></td></tr>');     
                }
            });
        }
    } 
}

问题是FilePath变量是可访问的,但是它“打印出来”总是相同的路径,而不是循环i所遵循的路径。

应用程序使用nodo-webkit构建,一切都很有效,这是我唯一无法弄清楚的问题。

感谢您的帮助!

1 个答案:

答案 0 :(得分:3)

在循环内创建的每个函数都关闭相同的FilePath(即它们不会各自得到它们自己的副本),这意味着它们每个都会看到变量执行时所具有的任何值。为了使这项工作符合您的预期,您需要对其进行排列,以便他们每个都获得自己的副本。由于JavaScript变量的范围限定为最近的封闭函数,因此将函数创建包装在一个立即调用的函数中,该函数接收所需的值作为参数:

(function(FilePath) {
    parser.on('metadata',  function (result) {
        if (result.picture.length == 0) {
            $("#track-table").append('<tr path="'+ FilePath +'"><td></td></tr>');
        } else {
            var picture = base64ArrayBuffer(result.picture[0].data);
            $("#track-table").append('<tr path="'+ FilePath +'"><td></td></tr>');     
        }
    });
})(FilePath);

在这种情况下,每个新函数都会关闭一个新的FilePath,从而产生想要的结果。