Javascript:仍然被instanceof运算符搞糊涂了

Har*_*ish 5 javascript inheritance instanceof

文章如下定义的instanceof:

instanceof运算符测试对象在其原型链中是否具有构造函数的prototype属性.

这是一个公平的解释,生活很好,直到我从Eloquent Javascript这本书中看到这个代码:

function TextCell(text) {
  this.text = text.split("\n");
}

TextCell.prototype.minWidth = function() {
  return this.text.reduce(function(width, line) {
    return Math.max(width, line.length);
  }, 0);
}

TextCell.prototype.minHeight = function() {
  return this.text.length;
}

TextCell.prototype.draw = function(width, height) {
  var result = [];
  for (var i = 0; i < height; i++) {
    var line = this.text[i] || "";
    result.push(line + repeat(" ", width - line.length));
  }
  return result;
}

function RTextCell(text) {
  TextCell.call(this, text);
}

RTextCell.prototype = Object.create(TextCell.prototype);

RTextCell.prototype.draw = function(width, height) {
  var result = [];
  for (var i = 0; i < height; i++) {
    var line = this.text[i] || "";
    result.push(repeat(" ", width - line.length) + line);
  }
  return result;
};
Run Code Online (Sandbox Code Playgroud)

让我们创建一个RTextCell实例并执行下面的c

var rt = new RTextCell("ABC");
console.log(rt instanceof RTextCell); // true
console.log(rt instanceof TextCell); // true
Run Code Online (Sandbox Code Playgroud)

我理解为什么第二个console.log的输出是"true" - 因为构造函数TextCell是原型链的一部分.

然而,第一个console.log让我困惑.

如果查看代码(从底部开始的第10行),RTextCell的原型将更新为新的Object,其原型设置为TextCell.prototype.

RTextCell.prototype = Object.create(TextCell.prototype);.

查看下面的快照,在对象"rt"的原型链中没有提到构造函数"RTextCell".那么,按照我在帖子开头提到的定义,输出不应该是假的吗?为什么它会返回真值?

我也读过这篇文章,但没有帮助我理解这个具体问题.

请参阅下面的按顺序查看rt,RTextCell,TextCell的快照.

RTextCell的快照 TextCell的快照

Dar*_*con 1

准确的措辞很重要。您谈论构造函数位于原型链中,但原始引用并未:

instanceof 运算符测试对象的原型链中是否具有构造函数的原型属性

所以这个表达式rt instanceof RTextCell实际上是在测试这样的东西(记住这__proto__不是标准的):

var p = rt.__proto__;
while(p)
{
  if(p == RTextCell.prototype)
    return true;
  p = p.__proto__;
}
return false;
Run Code Online (Sandbox Code Playgroud)

因此,即使该函数RTextCell没有在上面的对象树中直接引用,该RTextCell.prototype对象也是如此。