2012-09-25 42 views
0

我正在JavaScrit函數中的閉包範圍掙扎。下面的函數應該創建三個具有不同圖像的樣本(可以工作),然後當點擊這些樣本時,應該切換樣式表。有兩個函數的JavaScript閉包範圍

問題是,即使逐步顯示第一個函數中的theme變量確實會更改,也會將同一對象傳遞給switchTheme函數。

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

通過switchTheme(theme)使用將是theme是當函數被調用的狀態值,該值此時不綁定您創建一個匿名回調。使用閉包綁定特定的值:

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

謝謝。不完全確定,我知道這是爲什麼起作用,但確實如此。 – Echilon

+0

這段代碼會創建一個匿名函數,它的值爲't'並返回一個調用'switchTheme'的函數。然後,您立即調用該匿名函數,並將它傳遞給'theme'的當前值。希望有所幫助。 – deceze

+0

是的,我很困惑,但這看起來是正確的。你可以解釋嗎? – chovy

0

移動

var theme = switcherConfig.themes[themeName]; 

點擊而不是使封閉的,你可以使用.data像下面(只是替代)函數

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 
    } 
} 
+0

設置屬性標題時theme.title會失敗 –

0

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