Uncaught SyntaxError: Unexpected identifier in a setTimeout ()

2

I dynamically load the following file:

full.js

window.APP = {
  SKIN: 'FSKIN',
  Run: function( ) {
    var layout = {

    };

    console.log( 'Lanzando <full>' );
    debugger;
    setTimeout( window.SPINNER.stop( ), 2000 );
  }
}

By saying dynamics , I mean I charge it via AJAX, not with

<script src="full.js"></script>

When loading the page in the browser, it works fine. The rest of the code does what it has to do, the file is loaded, and the function APP.Run( ) is called.

When you reach debugger; , everything is correct. If I type in the console

  

typeof (SPINNER.stop)

answers me

"function"

But if I continue from there, or directly remove debugger , it shows me the indicated error

Uncaught SyntaxError: Unexpected identifier

followed by a code VM , and it does not show me the source code involved. There is no call stack or anything to look for.

Why do you show me that error?

EDITO

The SPINNER is a small external library: link

And I believe it as

window.SPINNER = new Spinner( CONFIG.SYSTEM.SPINNER ).spin( document.body );

The SPINNER itself works fine.

For what it's worth, the stack of calls would be:

ready( function( ) {
  ajax( URL, function( res ) {
    app = new Function( res );
    app( );
    APP.Run( );
  } );
} );

I do not use jquery , but I think it is understood.

EDIT 2

This is a modification I made to the full.js file:

window.APP = {
  SKIN: 'FSKIN',
  Run: function( ) {
    setTimeout( window.SPINNER.stop.call( window.SPINNER ), 2000 );
  }
}

The result is the same, Uncaught SyntaxError: Unexpected identifier .

Afterwards, I tried this:

window.APP = {
  SKIN: 'FSKIN',
  Run: function( ) {
    setTimeout( function( ) { window.SPINNER.stop( ); }, 2000 );
  }
}

Now yes!
It does not show any error, and everything works correctly.

I understand that by doing setInterval( ) , I am creating an event and placing it in the system event queue. To prevent possible problems, I use the fully qualified names of the variable and the method I use: window.SPINNER.stop( ) .

The original question still stands:

Why does this happen? What is the difference between calling the SPINNER.stop( ) method in or out of an anonymous function?

EDITO 3

What I've tried so far:

setTimeout( window.SPINNER.stop( ), 1000 );

Uncaught SyntaxError: Unexpected identifier

Serious error on my part. The parentheses, as indicated by OscarGarcia and Guz.

setTimeout( window.SPINNER.stop, 1000 );

No There is an error, but does not work . The SPINNER keeps turning.

setTimeout( function( ) { window.SPINNER.stop( ); }, 1000 );

If it works. There is no error All OK.

    
asked by Trauma 15.02.2017 в 08:04
source

1 answer

3
  

Note: You should not execute a function if you pass it as callback In fact, if you leave it with parentheses (execution) it will only be executed once since setTimeout accepts a function as first parameter and the execution of a function does not return anything ( undefined ); therefore, the timeout will not fulfill its purpose.

Problem

The error is referring to scope scopes or scopes . You are passing the function reference stop as callback without setting the scope to which you should reference stop .

When you do:

window.setInterval(SPINNER.stop, 3000);

The scope of stop will be global, that is window . Why? The reason is simple:

  

In JavaScript the scope of this will always be where it is executed.

Therefore, since the scope of setTimeout is window , then the scope of stop will also be window .

Solution

The solution is simple, you can do it in two ways:

  • Passing a closure as a callback to setInterval and executing stop in it.

    setInterval(function () { SPINNER.stop(); }, 3000);
    
  • Setting the scope of the stop method via bind .

    setInterval(SPINNER.stop.bind(SPINNER), 3000);
    

Using bind will create a new function by replacing the scope with the past by parameter.

Choose the way you choose, it will work correctly.

    
answered by 15.02.2017 / 20:39
source