a instanceof b returns false 即使 b 在 a 的原型链中
a instanceof b returns false even though b is in a's prototype chain
还有一个 instanceof
问题。
我正在使用来自 antlr4 解析器的一些自动生成的代码。解析器工作正常,我将它与 ace 一起插入,语法突出显示工作,......到目前为止一切顺利。但是现在发生了一件非常奇怪的事情。我写了自己的 parserTreeListener
,由于 instanceof
调用 return 错误结果而失败。
将问题分解为一个小程序是可行的。但是就像魔术一样,即使它使用相同的代码(解析器、词法分析器、监听器...),一切都很顺利
不够奇怪,在 chrome devtools 中调试问题,向我展示了对象 t
原型链 (__proto__) 确实是 TerminalNode
的一个实例但是尽管如此,调用 t instanceof TerminalNode
returns false
。
不幸的是,我无法发布主项目的代码,它失败了(至少现在还没有)。也许有人知道为什么以及何时会出现此类问题。
一些可能的解释(尽管我怀疑)
- 脚本加载了两次,TerminalNode 不等于 proto 的 TerminalNode
- 与工作线程中加载的同一个库发生冲突
antlr4 中的这段代码失败了:
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);
}
};
一些调试信息
两个脚本 return 在我键入时的断点处相同:
$ var obj = t; while(obj) console.log(obj = Object.getPrototypeOf(obj));
TerminalNode {}
ParseTree {}
SyntaxTree {}
Tree {}
Object {}
Object {}
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
虽然我没有解释,但为什么会发生这种奇怪的行为。双重包含的脚本是错误的根本原因。当我使用 Polymer 和 Webcomponents 时,多个组件包含相同的脚本。
通过将组件中的特定 <script ..>
标记移到主文档中,这些问题不再发生。
也许还有人知道,为什么会出现这样的错误?
还有一个 instanceof
问题。
我正在使用来自 antlr4 解析器的一些自动生成的代码。解析器工作正常,我将它与 ace 一起插入,语法突出显示工作,......到目前为止一切顺利。但是现在发生了一件非常奇怪的事情。我写了自己的 parserTreeListener
,由于 instanceof
调用 return 错误结果而失败。
将问题分解为一个小程序是可行的。但是就像魔术一样,即使它使用相同的代码(解析器、词法分析器、监听器...),一切都很顺利
不够奇怪,在 chrome devtools 中调试问题,向我展示了对象 t
原型链 (__proto__) 确实是 TerminalNode
的一个实例但是尽管如此,调用 t instanceof TerminalNode
returns false
。
不幸的是,我无法发布主项目的代码,它失败了(至少现在还没有)。也许有人知道为什么以及何时会出现此类问题。
一些可能的解释(尽管我怀疑)
- 脚本加载了两次,TerminalNode 不等于 proto 的 TerminalNode
- 与工作线程中加载的同一个库发生冲突
antlr4 中的这段代码失败了:
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);
}
};
一些调试信息
两个脚本 return 在我键入时的断点处相同:
$ var obj = t; while(obj) console.log(obj = Object.getPrototypeOf(obj));
TerminalNode {}
ParseTree {}
SyntaxTree {}
Tree {}
Object {}
Object {}
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
虽然我没有解释,但为什么会发生这种奇怪的行为。双重包含的脚本是错误的根本原因。当我使用 Polymer 和 Webcomponents 时,多个组件包含相同的脚本。
通过将组件中的特定 <script ..>
标记移到主文档中,这些问题不再发生。
也许还有人知道,为什么会出现这样的错误?