Javascript闭包返回未定义的
我继承了一个需要为我的工作更新的代码库。我正在慢慢地了解他们试图通过现有的关闭来完成什么,但是当我试图更新使用此功能的站点的一部分时,我陷入了困境。我将给出代码试图实现的基本概要,并看看是否有人可以提供帮助Javascript闭包返回未定义的,javascript,web,closures,Javascript,Web,Closures,我继承了一个需要为我的工作更新的代码库。我正在慢慢地了解他们试图通过现有的关闭来完成什么,但是当我试图更新使用此功能的站点的一部分时,我陷入了困境。我将给出代码试图实现的基本概要,并看看是否有人可以提供帮助 var TheObject = (function (){ var veryLargeDependantData = { var1: {}, var2: {}, var3: [], //Set these varia
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变量是函数的入口。当页面加载时,它调用initialize函数,一切正常。但是现在我需要将它添加到一个onclick事件中,用于和更早的页面,firebug控制台会说该变量未定义。在其他页面中,我可以毫无问题地使用它
我的问题是,到底是什么魔力使得闭包不属于这样一个可调用的名称空间。我有点不懂javascript,所以如果这个问题听起来有点误导,我很抱歉
onclick='TheObject.initialize();'
我假设您的意思是希望在单击事件处理程序中运行
initialize
函数,并且您当前正在尝试这样做:
TheObject.initialize();
如果是这种情况,问题在于对象
实际上指的是初始化
的返回值,因为您对立即调用的函数表达式的返回值调用了初始化
。很可能initialize
返回undefined
(很可能没有显式的return
语句)
要解决这个问题,您可能需要删除对
initialize
的立即调用,这将允许您在页面加载和其他任何地方使用上面显示的行。在这段代码中,对象的值将是veryLargeDependentData.initialize()
方法返回的值。如果initialize方法不返回任何内容,对象将未定义
一个简化的例子:
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();
您可以通过将对象设置为包含initialize方法的对象,然后在需要时再次运行该方法来解决此问题
var TheObject = (function () {
return {
initialize: function () {
}
}
})();
// initialize
TheObject.initialize();
// and again
TheObject.initialize();
请注意强>
原始作者可能希望initialize方法只运行一次。多次运行可能会给您的系统带来bug 似乎不必要的复杂,我不确定在这种情况下使用匿名函数和闭包会得到什么。你有什么理由不能简单地做到以下几点吗
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);
请注意,您希望删除内联事件。能否显示onclick
事件中的代码?verylargeDependentData()
在全局范围中不存在,因此您不能以那种方式调用它。调用它的唯一方法是当前通过Object.initialize()调用它。(由于拼写错误,很难说)verylargeDependentData
不是一个函数(除了超出范围之外),您实际上想用它做什么?当按下按钮而不是页面加载时初始化它?@jerry这正是我想要做的。我想在页面加载时加载它,但也要在onclick事件上加载它。顺便说一句,这是继承的代码,所以它可能不太原始。我仍然不确定返回语句在那里做什么。我认为他不想调用object initialize,他想初始化他的对象并将其数据保存在闭包中。但他把返回语句放在变量声明中,+有拼写错误。我想我明白你的意思,但问题有点混乱,所以除非他们更新它,否则我们无法真正知道OP的目的。我认为这些输入错误只是由于大幅削减代码以将其发布到此处而造成的。@jamesalardice所以您的意思是,如果我将对初始化函数的调用移到脚本的正下方,我应该可以随时调用该对象。我试过了。它仍然在说对象是未定义的。我删除了即时初始化,然后又调用了它,但运气不好。@MichaelGuantonio似乎你也有一个范围问题。尝试window.TheObject=…
(您的对象必须是全局的,才能从单击处理程序中看到)。这是一种不错的解释方式。因为我对javascript的整个内容都是新手,所以我对编写的代码不感兴趣,只想修改它的功能。但你是对的,将来某一天它应该遵循这种模式。