【问题标题】:Function cannot be called on possibly undefined value on iterator无法在迭代器上可能未定义的值上调用函数
【发布时间】:2017-10-20 07:13:14
【问题描述】:

Flow 认为以下是安全的:

const a: ?any = {};
if (a!=null) {
    console.log(a.toString());
}

...但在以下方面引发错误:

const m: Map<string, string> = new Map();
const iter = m.keys();
const iternext = iter.next();
if (iternext!=null) {
    const ignore = iternext.value(); // Flow doesn't like this
}

错误是:

call of method `value`. Function cannot be called on possibly undefined value

这是为什么呢? 使用最新的0.57.3 测试。

【问题讨论】:

    标签: javascript flowtype


    【解决方案1】:

    我相信错误消息是说iternext.value 可能是undefined

    iter.next() 实际上永远不会返回undefinednull,因此if 测试是不必要的。当迭代器耗尽时,它将返回{value: &lt;return value&gt;, done: true}。大多数生成器虽然没有返回值,所以它将是 {value: undefined, done: true},因此 Flow 说 “函数不能在可能未定义的值上调用”

    const m = new Map([['foo', 'bar']]);
    const iter = m.keys();
    console.log(iter.next());
    console.log(iter.next());
    console.log(iter.next());

    调用 iternext.value() 肯定是错误的,因为您有一个字符串映射。如果你有一个函数映射(并且迭代器没有用尽),你只能调用它。

    您可能想再次查看iterator protocol

    【讨论】:

      【解决方案2】:

      我被 Flow 错误消息误导了。将 value() 更改为 value 不会导致流错误。不过,我不确定我是否理解错误消息或 Flow 的想法。措辞似乎表明潜在的未定义值是iternext,这没有任何意义。

      为了公平起见,突出显示的文本似乎表明该问题与iternext 没有密切关系:

      【讨论】:

      • 当您执行foo.bar() 时,首先检索foo.bar 的值,然后调用该值。因为foo.bar 可以是undefined,所以您会看到此消息。更简单的例子:var foo = undefined; foo();。如果iternextundefined,则错误消息将类似于“无法访问可能未定义的值的属性”。我同意当你第一次阅读它时这听起来很奇怪(我相信这是因为我们“看到”foo.bar() 更多的是foo.(bar()) 而不是(foo.bar)()),但它在技术上是正确的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-21
      • 1970-01-01
      • 2019-03-27
      • 1970-01-01
      • 1970-01-01
      • 2015-08-01
      • 2016-11-26
      相关资源
      最近更新 更多