Нулевой прототип, Object.prototype и Object.create

Почему настройка свойства prototype для функции конструктора на null не препятствует вызовам объектов, созданных из этой функции, методам на Object.prototype, таким же образом, что установка прототипа на Object.create(null)

Вот почему это так:

function Foo(){}
Foo.prototype = null;
console.log(new Foo().toString); //outputs function toString() { [native code] } (or whatever)

function Foo(){}
Foo.prototype = Object.create(null);
console.log(new Foo().toString); //output undefined

Ответы

Ответ 1

Короче

Да, ваше наблюдение верное - функция, построенная с помощью оператора new, всегда будет иметь прототип объекта в этом случае Object.prototype, и это действительно не похоже на функцию, созданную с Object.create.


О том, почему

Это поведение полностью определено в спецификации языка ES5, на которой основан JavaScript. Давайте посмотрим на это.

В new:

Указав спецификацию метода [[Construct]], который указывает, как выполняется создание объекта с помощью оператора new, мы можем видеть, что указано следующее:

Если Type (proto) не является Object, установите внутреннее свойство [[Prototype]] объекта obj для стандартного встроенного объекта прототипа объекта, как описано в 15.2.4.

В Object.create:

С другой стороны, если мы проверяем спецификацию для Object.create, мы можем видеть, что Object.create(o) указывает:

Задайте внутреннее свойство [[Prototype]] объекта obj в O.

Это означает, что мы можем установить его, он также явно проверяет, что это null или Object в этом алгоритме (пожалуйста, следуйте ссылке на спецификацию и прочитайте ее:))

Таким образом, прототипом объектов, вызываемых с помощью new Foo, является Object.prototype, а не null. Невозможно создать объекты без прототипа без Object.create, используя только стандартные методы.