为什么我不能将console.log()直接设置为回调函数
此代码无法运行的原因
function callback(num, func) {
for(var i = 0; i < num; i++) {
func();
}
}
callback(4, console.log("Hello"));
我知道我必须这样做:
callback(4, function() { console.log("hello"); });
但我还是不明白为什么我必须那样做。
解决方案
让我们一步一步来帮助您直观地了解正在发生的情况。当解释器读取您的代码时,它会由内而外地计算函数表达式。也就是说:
callback(4, console.log("Hello"));
// ^------------------^---- is evaluated before "callback" is called.
将产生相同结果的更长形式的书写方式是:
var result = console.log("Hello");
callback(4, result);
console.log
函数没有定义的返回值(或者至少没有标准化的返回值)--尽管顺便说一句,Java脚本中的所有函数都会返回某些--如果未指定,则该值实际上是undefined
。因此,当您运行代码时,您实际上是在调用:
callback(4, undefined);
这意味着在callback
内部,尝试将func
作为函数调用将导致:
TypeError:未定义不是函数
这就是为什么您需要将您的逻辑封装在一个新的函数闭包中,从而func
获取对可调用Function
对象的引用。
如何整理我的代码?
通常在这种简单的情况下,您为解决问题所做的工作是完全可以接受的,但对于更复杂的逻辑,您通常会得到几个级别的嵌套回调(有时称为"回调汤")。为了提高代码重用常见的可读性,您可以引入一个函数工厂来隐藏肮脏之处,例如:
function myLogger(message){
return function(){
console.log(message);
}
}
callback(4, myLogger('hello'));
相关文章