JavaScript中的回调是空白函数吗

Are callbacks in JavaScript just blank functions?

本文关键字:空白 函数 回调 JavaScript      更新时间:2023-09-26

我一直在试着思考回调,出于好奇,我在todomvc中浏览了vanilla-js的源代码,发现了这个函数:

Store.prototype.findAll = function (callback) {
    callback = callback || function () {};
    callback.call(this, JSON.parse(localStorage[this._dbName]).todos);
};

下面的陈述是什么意思?

callback = callback || function () {};

这是否意味着回调只是空白函数?

另外callback.call(this)和CCD_ 2?

我试着修改这条线

callback.call(this, JSON.parse(localStorage[this._dbName]).todos);

callback(JSON.parse(localStorage[this._dbName]).todos);

但结果是一样的。为什么要做callback.call而不是简单的callback

JavaScript中的回调只是空白函数吗?

回调不仅仅是空白函数。它们是稍后可以调用的函数(通常带有一些参数(。有时,它们是可选的,主机函数会允许您传递回调或不传递回调。如果没有传递回调,宿主函数可以检测到它没有作为参数传递,并相应地调整其行为。

下面的陈述是什么意思?

callback=callback ||函数(({};

这是否意味着回调只是空白函数?

这是一种常见的设计模式,可以确保函数的参数在调用方未传递的情况下具有有意义的值,这样,即使调用方没有传递参数,函数也可以在内部进行并正常执行。

代码callback = callback || function () {};相当于:

if (callback) {
    callback = callback;
} else {
    callback = function() {};
}

在Javascript中,||运算符将结果指定为两个真操作数中的第一个(如果两者都不是真操作数,则指定为false(,因此如果callback有值,则它将成为||操作数的结果,从而获得callback = callback。否则,如果callback不是真的,它会指定callback具有默认函数值,该值允许函数的其余部分在假定callback具有合法值的情况下运行。这就避免了函数代码的其余部分在使用callback之前必须检查它是否具有合法值

另外,callback.call(this)callback(anything)

someFunction.call()允许您在函数运行时获得this的值。因此,callback.call(this)使回调在运行时具有与当前函数相同的callback(anything)0值。如果您只是在没有.call()的情况下执行了callback(...),那么this将采用默认值,该值要么是window对象,要么如果在严格模式下运行,则为undefined

如果特定回调在其代码中没有引用this的值,那么使用或不使用.call()的结果不会有什么不同,但在这种情况下,回调提供的一个额外功能是,它可以通过访问回调中的this值来访问正在使用的Store对象的当前实例。


这样设置this的值可以使用对象的方法作为直接回调,因为这与对象方法的调用约定相同。

所以,如果你有一个像这样的Store对象:

var s = new Store();

而且,有一个名为setName()的对象方法,它使用this来引用自己的对象实例,您可以这样做:

s.findAll(s.setName);

这只会起作用,因为callback.call(this)在回调中将实例值设置为this的值。

不,回调不是"空白"的。在这里,函数接收一个回调作为参数,并简单地确保它是一个函数。如果没有传递回调,它将被设置为一个空函数,但至少它是一个可以调用的函数。将参数设置为默认值(此处为空函数(简化了以下代码,否则,如果回调不是函数,则需要一堆if..else条件才能执行不同的操作。

关于问题的另一部分,请参见;这个";关键词工作?。

模式:

function foo(bar) {
  bar = bar || someDefault;
  ...
}

是一种常见(但已过时(的方法,用于在调用方未定义函数参数的情况下将其设置为默认值。

在这种情况下,该函数利用所有函数都是truthy和JS的异常OR运算符,如果未设置callback,则将其设置为空(nop(函数。您可以在以下示例中看到这种行为:

var barDefault = 'No value provided!';
function foo(bar) {
  bar = bar || barDefault;
  console.log(bar);
}
foo(); // No value provided, since no arguments passed
foo(3); // Argument passed, value provided
foo(0); // Tricky case: falsy argument passed, so function assumes no value was provided

正如您从示例中看到的,当传递了一个错误的参数时,这种模式可能会导致问题,因为OR运算符将返回到默认值。要解决此问题,请使用:

bar = typeof bar !== 'undefined' ? bar : barDefault;

将显式检查未定义的参数。

使用ES6和默认参数值,这可以更习惯地表示为:

function foo(bar = someDefault) {
  ...
}