Closing Javascript returns undefined

I have inherited the code base that I need to update for my work. I am slowly learning what they are trying to accomplish with a closure that exists, but I am stuck when I try to update part of the site using this functionality. I will give a basic plan of what the code is trying to execute, and see if anyone can help.

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(); 

Since I obviously cannot show the production code on the site, this will have to do. But basically the veryLargeDependentData variable is the input to the function. When the page loads, it calls the initialization function, and everything is fine. But now I need to add this to the onclick event for an older page, and the firebug console says the variable is undefined. On other pages I can use it without problems.

My question is what happens in magic, which causes the closure to not be part of the called namespace like this. I'm a bit of javascript nOOb, so I apologize if the question sounds wrong.

 onclick='TheObject.initialize();' 
+4
source share
3 answers

I assume that you mean that you want to run the initialize function in the click event handler, and you are currently trying to do this as follows:

 TheObject.initialize(); 

If so, the problem is that TheObject actually refers to the return value of initialize , since you called initialize on the return value of the expression called immediately. And there is a chance that initialize returns undefined (most likely, it does not have an explicit return ).

To solve this problem, you probably want to remove the initalize immediate call, which will allow you to use the line shown above both on the page load and elsewhere.

+5
source

In this code, the TheObject value will be what the veryLargeDependentData.initialize() method returns. If the initialization method returns nothing, TheObject will be undefined.

A simplified example:

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

You can break it down into the following execution order:

 // 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(); 

You can get around this by setting TheObject as an object containing the initialization method, then run this method again when you need it.

 var TheObject = (function () { return { initialize: function () { } } })(); // initialize TheObject.initialize(); // and again TheObject.initialize(); 

NOTE!

Perhaps the original author suggested that the initialization method runs only once. Running it more than once can lead to errors in your system!

+2
source

It seems overly complicated, I'm not sure what happens when using an anonymous function and closing in this case. Is there a reason you can't just do the following?

 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); 

Note that you want to remove the inline event.

+1
source

Source: https://habr.com/ru/post/1483811/


All Articles