为什么我不能将console.log()直接设置为回调函数

2022-08-06 00:00:00 callback javascript this 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'));

相关文章