即使b位于原型链中,instanceof b也会返回false

时间:2016-07-12 16:27:33

标签: javascript antlr4 instanceof

另一个instanceof问题。 我正在使用antlr4解析器中的一些自动生成的代码。解析器工作正常,我将它与ace一起插入,语法突出显示工作,...到目前为止一切顺利。但现在发生了一件非常奇怪的事情。我编写了自己的parserTreeListener,由于instanceof调用返回错误的结果而失败。

将问题分解为一个小程序。但就像魔法一样,即使它使用相同的代码(Parser,Lexer,Listener,......),一切都很顺利。

在chrome devtools中调试问题并不奇怪,向我显示对象t原型链(__proto__)确实是TerminalNode的一个实例,但调用t instanceof TerminalNode仍返回{{ 1}}。 here it works here it doesn't

不幸的是,我无法发布主项目的代码,它失败了(至少现在还没有)。也许有人知道为什么以及什么时候出现这样的问题。

一些可能的解释(即使我怀疑)

  • 脚本加载两次,TerminalNode不等于proto的TerminalNode
  • 与工作线程中加载的相同库发生冲突

在antlr4的这段代码中,它失败了:

false

一些调试信息

当我输入时,两个脚本在断点处返回相同的内容:

ParseTreeWalker.prototype.walk = function(listener, t) {
var errorNode = t instanceof ErrorNode ||
        (t.isErrorNode !== undefined && t.isErrorNode());
if (errorNode) {
    listener.visitErrorNode(t);
} else if (t instanceof TerminalNode) { /*here t fails on first TerminalNode*/
    listener.visitTerminal(t);
} else {
    this.enterRule(listener, t);
    for (var i = 0; i < t.getChildCount(); i++) {
        var child = t.getChild(i);
        this.walk(listener, child);
    }
    this.exitRule(listener, t);
}
};

2 个答案:

答案 0 :(得分:0)

a instanceof b检查a是否继承自b.prototype,而不是b

如果您想测试b本身是否出现在a的原型链中,您可以使用

b.isPrototypeOf(a);

一些例子:

[] instanceof Array;                           // true
Array.isPrototypeOf([]);                       // false
Object.getPrototypeOf([]) === Array;           // false

[] instanceof Array.prototype;                 // TypeError
Array.prototype.isPrototypeOf([]);             // true
Object.getPrototypeOf([]) === Array.prototype; // true

答案 1 :(得分:0)

即使我没有解释,这种奇怪的行为怎么可能发生。双包含脚本是错误的根本原因。当我使用Polymer和Webcomponents时,多个组件包含相同的脚本。

通过将特定<script ..>标记从组件中移出到主文档中,这些问题不再发生。

也许还有人有线索,为什么会导致这样的错误?