setTimeout callback argument

前端 未结 4 1570
伪装坚强ぢ
伪装坚强ぢ 2020-11-29 22:20

Let\'s consider this piece of JavaScript:

function Person(name) {
    this.name = name;
}

Person.prototype.showName = function() {
    alert(this.name);
}

         


        
相关标签:
4条回答
  • 2020-11-29 23:01

    Your question really has nothing at all to do with setTimeout. You simply need to understand the difference between a function call and a reference to a function.

    Consider these four assignments:

    var one = function() { mike.showName(); };
    var two = mike.showName;
    var three = mike.showName();
    var four = (function() { mike.showName(); })();
    

    The first two assign a reference to a function to their respective variables. The last two, however, call functions (that's what the parens are for) and assign their return values to the vars on the left-hand side.

    How this relates to setTimeout:

    The setTimeout function expects as its first argument a reference to a function, so either one or two above would be correct, but three and four would not. However, it is important to note that it is not, strictly speaking, a mistake to pass the return value of a function to setTimeout, although you'll frequently see that said.

    This is perfectly fine, for example:

    function makeTimeoutFunc(param) {
        return function() {
            // does something with param
        }
    }
    
    setTimeout(makeTimeoutFunc(), 5000);
    

    It has nothing to do with how setTimeout receives a function as its argument, but that it does.

    0 讨论(0)
  • 2020-11-29 23:03

    setTimeout(mike.showName(), 5000); executes mike.showName() immediately and passes the return value to setTimeout()

    setTimeout(function(){ mike.showName(); }, 5000); passes a pointer to the function instead. That way setTimeout can execute the function, rather than it's return value.

    0 讨论(0)
  • 2020-11-29 23:05

    If the accepted answer is just too long to read:

    setTimeout(mike.showName(), 5000);
    

    This will execute whatever mike.showName() returns after 5,000 milliseconds.

    setTimeout(function(){ mike.showName(); }, 5000);
    

    This will execute anonymous function after 5000 milliseconds that calls mike.showName() , the actual function.

    Another way to achieve same effect:

    setTimeout(mike.showName.bind(mike), 5000);
    
    0 讨论(0)
  • 2020-11-29 23:10

    It's not a performance issue. One of the ways you showed simply doesn't work (it calls the function immediately instead of when the timeout fires).

    setTimeout(mike.showName(), 5000); will execute the showName function and sets its return value as the timeout callback which won't work.

    setTimeout(function(){ mike.showName(); }, 5000); creates an anonymous function and sets this as the timeout callback. When the timeout fires, the function is called and calls your showName() function.

    Fyi, setTimeout('mike.showName();', 5000); would also work. But don't do that - it's just as bad as using eval(). Besides that it makes your code less readable since the code in the string cannot be syntax-highlighted.

    0 讨论(0)
提交回复
热议问题