Javascript变量范围和对象作为参数传递给函数

时间:2015-10-02 11:12:15

标签: javascript gulp laravel-elixir

我使用Laravel Elixir和Laravel-Elixir-SpriteSmith创建一些精灵图标。我在不同的文件夹中存储了至少3种不同的图标大小,因此我尝试迭代这些文件夹并执行任务以为每个文件夹生成精灵:

我的问题是,在传递给blue <- rgb(0, 0, 1, alpha=0.5) red <- rgb(1, 0, 0, alpha=0.5) barplot(heights1, widths1, space=0, col=blue) barplot(heights2, widths2, space=0, col=red, add=TRUE) 的第二个参数的cssOpts.cssSelector函数中,mix.spritesmith的值始终是最后一个值。

代码更好地解释了:

set

如何在每个循环中将正确的值传递给函数?

2 个答案:

答案 0 :(得分:2)

您遇到的问题称为后期绑定。您可以在多个SO问题上阅读相关内容,例如:Late binding onclick event

您基本上需要创建一个新范围,该范围将具有绑定到它的特定值set

cssSelector: (function(innerSet) {
    return function(item) {
        console.log(innerSet.size);
        return '.icon' + innerSet.size + '-' + item.name.replace('_', '-');
    };
})(set)

答案 1 :(得分:1)

我同意其他人,这是由于javascript中的闭包和变量提升工作原因:var set是上层函数范围的一部分,而不是循环。因此,在执行cssSelector时,set等于数组中的最后一个元素。

您可以使用@ ralh的方式,或使用forEach方法:

var sources = [{
    size: 16,
    source: 'resources/bower_components/famfamfam-silk/dist/png'
}, {
    size: 22,
    source: 'resources/assets/icons/22'
}, {
    size: 38,
    source: 'resources/assets/icons/38'
}];

sources.forEach(function (set) {
    mix.spritesmith(set.source, {
        imgOutput: 'public/icons',
        cssOutput: 'public/css',
        imgName: set.size + '.png',
        cssName: 'icons-' + set.size + '.css',
        imgPath: '../../icons/' + set.size + '.png',
        cssOpts: {
            cssSelector: function(item) {
                console.log(set.size); //PROBLEM HERE. Always prints 38! Should print 16 - 22 - 38.
                return '.icon' + set.size + '-' + item.name.replace('_', '-');
            }
        }
    });
})