JavaScript Closure Scope有两个函数

时间:2012-09-25 08:57:33

标签: javascript function closures

我正在努力解决JavaScrit函数中的闭包范围。下面的函数应该创建三个具有不同图像的样本(可以工作),然后单击这些样本时,应该切换样式表。

问题是同一个对象被传递给switchTheme函数,即使单步执行显示第一个函数中的theme变量确实发生了变化。

var switcherConfig = {
    themes: 
        {
            'Orangeness': {
                folder: 'ui-lightness'
            },
            'Red Matter': {
                folder: 'blitzer'
            },
            'Flubber': {
                folder: 'south-street'
            }
        }
}
function createThemeSwitcher(placeholderSelector) {
    for (var themeName in switcherConfig.themes) {
        var theme = switcherConfig.themes[themeName];
        var anchor = $('<a/>')
            //.text(theme.title)
            .attr('title', theme.title)
            .attr('href', '#')
            .on('click', function () { switchTheme(theme); })
            // append to DOM etc
    }
}
function switchTheme(theme) {
    var themeDirectory = switcherConfig.baseDirectory + '/' + theme.folder + '/';
    // 'theme' variable is always the last in my 'themes' config object
}

3 个答案:

答案 0 :(得分:3)

switchTheme(theme)使用的值将是theme在调用函数时所处的状态,该值在您创建匿名回调时不受约束。使用闭包来绑定该特定值:

.on('click', (function (t) {
    return function () { switchTheme(t); };
})(theme))

答案 1 :(得分:0)

移动

var theme = switcherConfig.themes[themeName];

点击功能

function createThemeSwitcher(placeholderSelector) {
    for (var themeName in switcherConfig.themes) {

        var anchor = $('<a/>')
            //.text(theme.title)
            .attr('title', theme.title)
            .attr('href', '#')
            .on('click', function () { 
                         var theme = switcherConfig.themes[themeName];
                         switchTheme(theme); 
            })
            // append to DOM etc
    }
}

答案 2 :(得分:0)

您可以使用下面的.data(只是替代方案)而不是关闭:

var switcherConfig = {
    themes: 
        {
            'Orangeness': {
                title:"Orangeness",
                folder: 'ui-lightness'
            },
            'Red Matter': {
                                title:'Red Matter',
                folder: 'blitzer'
            },
            'Flubber': {
                title:'Flubber',
                folder: 'south-street'
            }
        }
}
function createThemeSwitcher(placeholderSelector) {
    for (var themeName in switcherConfig.themes) {
        var theme = switcherConfig.themes[themeName];
        var anchor = $('<a/>')
            .data("theme",theme)
            .attr('title', theme.title)
            .attr('href', '#')
            .html(theme.title)
            .on('click', function () { switchTheme($(this).data("theme")); })
            $("body").append(anchor);
    }
}
function switchTheme(theme) {
    alert(theme.title)
}

Demo