1

我试图在 JavaScript中传递一个callback函数,但是在执行函数时我得到“未定义”。self-invoking functiondone

我读了这个答案来写下面的代码:

function done() {
    console.log(dateFilter.getI());
    console.log(dateFilter.getF());
}

var dateFilter = (function(callback) {
    var _dInicio = new Date(), _d = new Date(),
        _dFim = new Date(_d.setMonth(new Date().getMonth() - 1));
    return {
        getI: function() { return _dInicio; },
        getF: function() { return _dFim; },
        setI: function(d) { _dInicio = d; },
        setF: function(d) { _dFim = d; }
    }, callback();

 })(done);

也许我错误地使用了逗号运算符,但我认为这应该可行。有人可以指出我在哪里误解了什么?

4

3 回答 3

3

done在 a 之后调用该函数return,此外,您没有传递 param dateFilter

return { -> return before calling callback `function`.
    getI: function() { return _dInicio; },
    getF: function() { return _dFim; },
    setI: function(d) { _dInicio = d; },
    setF: function(d) { _dFim = d; }
}, callback( );
            ^
            |_ Calling callback without param `dateFilter`

看看这个代码片段

function done(dateFilter) {
  console.log(dateFilter.getI());
  console.log(dateFilter.getF());
}

(function(callback) {
  var _dInicio = new Date(),
    _d = new Date(),
    _dFim = new Date(_d.setMonth(new Date().getMonth() - 1));

  callback({
    getI: function() {
      return _dInicio;
    },
    getF: function() {
      return _dFim;
    },
    setI: function(d) {
      _dInicio = d;
    },
    setF: function(d) {
      _dFim = d;
    }
  });

})(done);

看?现在正在打印值。

于 2018-02-06T17:38:25.530 回答
2

这不起作用的两个原因:

  • 您正在callback使用逗号运算符返回结果,但done不返回任何内容
  • 您正在尝试dateFilter在 IIFE 初始化期间使用dateFilter- 它尚未分配返回值

绝对没有理由将回调与 IIFE 一起使用。写吧

var dateFilter = (function() {
    var _dInicio = new Date(), _d = new Date(),
        _dFim = new Date(_d.setMonth(new Date().getMonth() - 1));
    return {
        getI: function() { return _dInicio; },
        getF: function() { return _dFim; },
        setI: function(d) { _dInicio = d; },
        setF: function(d) { _dFim = d; }
    };
}());

console.log(dateFilter.getI());
console.log(dateFilter.getF());
于 2018-02-06T17:39:23.940 回答
1

真的很亲近。您对逗号运算符的预感是正确的。而且我认为有一种更好的方法来连接你的done()回调,这样代码就更健壮了,事情发生的顺序也更清晰了。

首先,让我们看一下return声明。所有的 return 语句都做件事(评估返回值,然后返回它),但是由于逗号,这个是做三个,按以下顺序:

  1. 评估对象字面量{ getI:... }
  2. 评估callback(),这意味着调用 callback()
  3. 返回 的返回值callback(),因为逗号运算符返回它的第二个操作数。

因此,请注意callback()实际上在您的函数返回之前被调用,因此它发生 dateFilter具有值之前。(而且,即使它确实有一个值,它也将是 的返回值callback(),这是未定义的。)

而且我认为您的代码还有另一个方面值得一看。回调通常带有参数。考虑它的最简单方法是:您将其传递给回调,而不是返回一个值。

通常,如果您传递参数而不是副作用共享变量,则代码更易于阅读和调试。

我刚刚对您的代码进行了一项更改,它正在工作:

function done(dateFilter) {
    console.log(dateFilter.getI());
    console.log(dateFilter.getF());
}

(function(callback) {
    var _dInicio = new Date(), _d = new Date(),
        _dFim = new Date(_d.setMonth(new Date().getMonth() - 1));
    callback({
        getI: function() { return _dInicio; },
        getF: function() { return _dFim; },
        setI: function(d) { _dInicio = d; },
        setF: function(d) { _dFim = d; }
    });

 })(done);

那么,我做了什么?

  • 我没有对值产生副作用dateFilter,而是将其直接传递给callback.

这意味着:语句中没有逗号运算符,也不需要对全局值return产生副作用。dateFilterdateFilter现在是doneistead 的参数。)

我希望这能为你澄清事情。干杯!

于 2018-02-06T18:02:01.543 回答