Instanceof проверяет работу над подклассом без установки конструктора

У меня есть следующий код JavaScript

function Parent() {
}

function Child() {
}

Child.prototype = Object.create(Parent.prototype);

Обратите внимание на отсутствие утверждения

Child.prototype.constructor = Child;

Я понимаю, что, поскольку свойство constructor не было установлено, проверки instanceof должны завершиться неудачно для новых экземпляров класса Child.

var child = new Child();
child instanceof Child; //Should give false

Я проверил, что конструктор неправильно установлен введите описание изображения здесь

Но когда я запустил child instanceof Child, он дал мне истинную

введите описание изображения здесь

Но это должно быть false, поскольку свойство конструктора не установлено на прототипе Child как Child.

Окружающая среда

Google Chrome Version 48.0.2564.109 (64-bit)
Ubuntu 14.04 LTS

Ответ 1

Мое понимание состоит в том, что поскольку свойство конструктора не было установлено, проверка экземпляра должна завершиться неудачно для новых экземпляров класса Child.

Нет, это неверно. Фактически, до ES2015 (иначе ES6) свойство constructor не использовалось ни для чего вообще в самом JavaScript. Он был определен как существующий на объектах по умолчанию, время выполнения назначает свойство prototype для функций, но не используется.

instanceof вообще не заботится о construtor. Рассмотрим:

o instanceof Foo

instanceof будет выглядеть, если объект Foo.prototype указывает на то, что находится в цепочке прототипов o. (Если "цепочка прототипов" не является знакомым термином, см. * В конце ответа, а затем возвращайтесь.) Если это так, он возвращает true; если нет, он возвращает false.

Например, здесь концептуальная реализация instanceof, ручная размахивая некоторыми деталями:

function isAnInstance(obj, func) {
    var p;
    for (p = Object.getPrototypeOf(obj); p; p = Object.getPrototypeOf(p)) {
        if (p === func.prototype) {
            return true;
        }
    }
    return false;
}

Хотя он был заменен спецификацией ES2015, я привяжусь к спецификации ES5, потому что он написан на более доступном языке, и этот аспект не изменился: instanceof эффективно просто вызывает функцию [[HasInstance]] внутренний метод, указанный здесь.

Мы можем видеть, что constructor не участвует в вашем вопросе, а также из этой простой демонстрации:

var p = {};
var o = Object.create(p);
var Foo = function() {};
Foo.prototype = p;
snippet.log(o instanceof Foo); // true
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>