0

I'm searching for access a window object into a function (actually, an ajax callback function but nevermind). So, I found a tuto where the guy explain my problem and why I have this problem but he doesn't resolve it.

Well, when I want to access the window object and I create an alert, the variable is undefined. And I understood why (I think). It's because when the global variable is in a function, everything in this function is protected.

Here is his code :

(function(){
    var foo = "Hello, window";

    var bar = function(){
         var foo = "Hello, function";

         alert(window.foo);
    };

    bar();
}());

So, my problem is quite the same. I have an object (with handsontable but it isn't important).

var hotTraitement = new Handsontable

I define it in global. So it can represent foo = "Hello, window". And I'm trying to use it in my callback function :

function callback(){
    alert(window.hotTraitement);
} 

And it's undefined. So I don't know how to do to get my object in my function and the tuto doesn't explain it. Can someone help me please ?

(If someone wants it, here is the link of the tuto : https://www.youtube.com/watch?v=VSgSNQ1-KBo&spfreload=10 )

EDIT :

This is my entire code :

<script>
//Where I define my object "hotTraitement"
var container = document.getElementById('tab_traitement');
var hotTraitement = new Handsontable(container, {
    data: data_traitement,
    stretchH: 'all',
    minSpareRows: 1,
    observeChanges : true,
    rowHeaders: false,
    colHeaders: false,
    contextMenu: true
});
</script>

//The function where I want to get that object
<script>
function insertTraitementCallback(responseObject,ioArgs)
{   
    alert(hotTraitement);   
}

</script>

//My ajax request where I call my callback function
<script type="text/javascript">
    $(document).ready(function()
    {
        $('#submit_button_traitement').click(function()
        {
            $.post("ajaxUpdate.php",{arr:data_traitement,id_essai,table,idTable}, insertTraitementCallback,'json');         
        });
    });

</script>
Erlaunis
  • 1,433
  • 6
  • 32
  • 50

2 Answers2

1

Well, the problem in your case is that the outer foo is not global. Everything is inside a function, which means your variables are not attached to window, but to your local function scope.

The only problem why you can't access the outer foo is because you're shadowing it with an inner foo. The practical, sane and simple solution is to simply avoid shadowing the name:

(function(){
    var foo = "Hello, outer";

    var bar = function(){
         var foo2 = "Hello, function";

         alert(foo);  // Hello, outer
    };

    bar();
}());
deceze
  • 510,633
  • 85
  • 743
  • 889
  • Thanks, but in my case, my object is out of the function, and it's undefined anyway. – Erlaunis Aug 10 '15 at 08:09
  • What does "out of the function" mean? Where exactly is it being defined? – deceze Aug 10 '15 at 08:10
  • Out of my callback function. Like : `var hotTraitement = new Handsontable ... function callback(){ //Get the hotTraitement here} ` – Erlaunis Aug 10 '15 at 08:12
  • As long as that callback function is defined in the same **lexical scope** as the variable, you have access to it from inside your callback function. Again, look at my example above. From inside `bar` you have perfectly fine access to `foo` without doing anything more. – deceze Aug 10 '15 at 08:17
  • You will have to show your actual code that "doesn't work". I can explain to you why your example doesn't work, which I did. I can't tell you why your actual code doesn't work, since you're not showing it. – deceze Aug 10 '15 at 08:23
  • That should indeed work as is. `insertTraitementCallback` is defined in the same lexical scope as `hotTraitement`. – deceze Aug 10 '15 at 08:45
  • I know, but hotTraitement is undefined :/ – Erlaunis Aug 10 '15 at 08:50
0

Your Foo variable isn't global scope in your code above, it's scoped within the IIFE. To make it global (and therefore accessible in the way you're looking to use it here), you'd need to declare it outside the IIFE. Alternatively, if you assign the result of your IIFE to a variable in global scope, and return an object from it, you'd be able to refer to the methods within that returned object as your callback as you describe. This is commonly used to namespace JavaScript. You can find more details of a similar approach in the section titled 'The module pattern: private data and private initialisation' here: http://www.2ality.com/2011/04/modules-and-namespaces-in-javascript.html . Essentially, you return an object that defines your method within it and return it from the IIFE like so:

var MyNamespace = (function() {
    function myInternalMethod() {
        //Do whatever your function does here...
    }

    return {
        myPublicFunction() {
            return myInternalFunction();
        }
    }
})();

And your callback could then be set to MyNamespace.myPublicFunction because MyNamespace would be in global scope.

Chris Disley
  • 1,286
  • 17
  • 30
  • So I had to declare my object in `myInternalMethod` ? And I need to return that object with `myPublicFunction` to access it after ? – Erlaunis Aug 10 '15 at 08:21
  • The value that's returned from the IIFE that we assign here to MyNamespace variable will be accessible outside the IIFE by using MyNamespace.[whatever]. In this instance, myInternalMethod is the function you're trying to use as a callback to your AJAX call, and MyNamespace.myPublicFunction is what you'd pass to that AJAX function so that it's available outside the scope of the IIFE. – Chris Disley Aug 10 '15 at 08:27
  • So, I tried something but honestly, I don't understand every thing :/ So I tried : `var myFunction = (function(){ var hotTraitement = new ... function callback(){} }());` – Erlaunis Aug 10 '15 at 08:52
  • But when I call my ajax callback, I tried `myFunction.callback` and it doesn't work (*myFunction is undefined*), but I'm not sure :/ – Erlaunis Aug 10 '15 at 08:54