4

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

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 事件中,并且萤火虫控制台说该变量未定义。在其他页面中,我可以毫无问题地使用它。

我的问题是发生了什么魔法导致闭包不属于这样的可调用命名空间的一部分。我有点 javascript noOOb,所以如果这个问题听起来有误导性,我深表歉意。

onclick='TheObject.initialize();'
4

3 回答 3

5

我假设您的意思是您想initialize在单击事件处理程序中运行该函数,而您目前正尝试这样做:

TheObject.initialize();

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

为了解决这个问题,您可能希望删除对 的立即调用initalize,这将允许您在页面加载和其他任何地方都使用上面显示的行。

于 2013-05-31T14:45:50.577 回答
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为包含初始化方法的对象来解决此问题,然后在需要时再次运行该方法。

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

// initialize
TheObject.initialize();

// and again
TheObject.initialize();

请注意!

原作者可能打算让初始化方法只运行一次。多次运行它可能会在您的系统中引入错误!

于 2013-05-31T14:57:27.383 回答
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);

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

于 2013-05-31T16:00:37.347 回答