Javascript闭包返回undefined

时间:2013-05-31 14:42:09

标签: javascript web closures

我继承了我需要为我的工作更新的代码库。我正在慢慢地学习他们正在尝试使用现有的闭包来完成什么,但是在尝试更新使用此功能的网站的一部分时我遇到了困难。我将给出代码试图完成的基本概述,看看是否有人可以提供帮助。

var TheObject = (function (){
    var veryLargeDependantData = {
        var1: {}, 
        var2: {}, 
        var3: [],
        //Set these variables via functions
        function1: function f1(data){...}, 
        function2: function f2(data){...}, 
        initialize: function initialize() { //set values for var1... var3}
     };

     return {initialize: veryLargeDependentData.initialize};
})().initialize(); 

由于我显然无法在网站上显示生产代码,因此必须这样做。但基本上,VeryLargeDependentData变量是函数的入口。当页面加载时,它调用初始化函数,一切都很愉快。但是现在我需要将它添加到onclick事件和旧页面,而firebug控制台说该变量是未定义的。在其他页面中,我可以毫无问题地使用它。

我的问题是,正在发生什么导致闭包不能成为像这样的可调用命名空间的一部分。我有点像javascript nOOb,所以如果问题听起来有误,我会道歉。

onclick='TheObject.initialize();'

3 个答案:

答案 0 :(得分:5)

我认为你的意思是你想在点击事件处理程序中运行initialize函数,而你当前正试图这样做:

TheObject.initialize();

如果是这种情况,问题是TheObject实际上引用了initialize的返回值,因为您在立即调用的函数表达式的返回值上调用了initialize。并且initialize可能会返回undefined(很可能,它没有明确的return语句。)

要解决此问题,您可能希望删除对initalize的即时调用,这样您就可以在页面加载和其他任何位置使用上面显示的行。

答案 1 :(得分:2)

在此代码中,TheObject的值将是veryLargeDependentData.initialize()方法返回的值。如果initialize方法什么都不返回,则TheObject将是未定义的。

简化示例:

var TheObject = (function () {
  return {
    initialize: function () { 
      // stuff happens here, but importantly, there's nothing returned
    }
  }
})().initialize();

您可以将其分解为以下执行顺序:

// the value of step_one is a function that will return an object when it is run
var step_one = (function () {
  return {
    initialize: function () {
      // ...
    }
  }
});

// after running the function step_one, step_two will be an object
// containing one key - initialize - which is a function
var step_two = step_one();

// since initialize doesn't return anything, TheObject is set to undefined.
var TheObject = step_two.initialize();

您可以通过将TheObject设置为包含initialize方法的对象来解决此问题,然后在需要时再次运行该方法。

var TheObject = (function () {
  return {
    initialize: function () {
    }
  }
})();

// initialize
TheObject.initialize();

// and again
TheObject.initialize();

请注意!

原作者可能打算将initialize方法只运行一次。多次运行可能会在系统中引入错误!

答案 2 :(得分:1)

看起来不必要地复杂,我不确定在这种情况下使用匿名函数和闭包获得了什么。有什么理由你不能简单地做以下事情吗?

var TheObject = {
    var1: {}, 
    var2: {}, 
    var3: [],
    //Set these variables via functions
    function1: function(data){...}, 
    function2: function(data){...}, 
    initialize: function(){alert("initialize");}
};

var initButton = document.getElementById("initButtonName");
initButton.addEventListener("click", TheObject.initialize);

请注意,您要删除内联事件。