JavaScript中setTimeout回调函数参数传递方式解析
为什么两种
setTimeout调用方式的区别这么大? 先明确核心点:setTimeout的第一个参数需要的是一个函数引用,而不是函数执行后的结果。
先看你写错的调用方式:
setTimeout(greet('John', sayName), 2000);
这里greet('John', sayName)加了括号,意味着立即执行greet函数,而不是把greet本身传给setTimeout。因为greet函数里没有return语句,它执行后返回的是undefined。所以这行代码等价于:
// 先立即执行greet,输出Hello world和Hello John greet('John', sayName); // 然后把undefined传给setTimeout,相当于什么都不会延迟执行 setTimeout(undefined, 2000);
这显然和你想要的“延迟2秒执行greet”完全不符。
再看正确的调用方式:
setTimeout(greet, 2000, 'John', sayName);
这里第一个参数是greet(没有括号),传递的是**greet函数的引用**——相当于告诉setTimeout:“2秒后,你帮我调用这个greet函数”。
而setTimeout的第三个及以后的参数,会在调用目标函数时自动传给它。也就是说,2秒后setTimeout会帮你执行:
greet('John', sayName);
这就实现了延迟2秒执行greet的效果。
再延伸一下函数作为参数的本质
JavaScript里函数是“一等公民”,可以像字符串、数字一样当作参数传递。当你传递**函数名(不加括号)**时,传递的是函数本身的引用,接收方可以在需要的时候调用它;而加括号的话,是立即执行函数,传递的是函数执行后的返回值。
比如例子里greet的第二个参数myFunction,你传递的是sayName(函数引用),所以greet内部可以调用myFunction(name),也就是执行sayName(name)——这也是回调函数的核心逻辑:把函数传给另一个函数,让它在合适的时机执行。
内容的提问来源于stack exchange,提问作者Russ Urquhart
相关产品推荐
相关产品推荐

