Когда вы Object.setPrototypeOf(f, ... )
, цепочка фактически 3 длинная:
Прототип o
равен f
. Прототип f
равен {c:3}
.
Таким образом, ваши примеры не эквивалентны друг другу:
1) В первом примере вы добавляете свойство c
непосредственно к прототипу, который будут использовать экземпляры f
, поэтому прототип o
содержит c
, поскольку f
является конструктором для o
.
В последних двух примерах Вы добавляете c
к прототипу f
, поэтому прототип f
был создан с помощью. Помните, что функции также являются просто объектами и что вы устанавливаете прототип функции, которую вы используете в качестве конструктора. Таким образом, протокол o
содержит протокол f
, который содержит c
.
2) Во втором примере вы получаетеPrototypeOf () o
. В третьем вы получаете PrototypeOf () f
. Следовательно, только 3-й пример снова показывает c
.
3) Если вы осмотрите элемент в chrome, вы увидите, что конструктор 2-го примера равен f
, так как вы спрашиваете у прото o
.
В третьем примере вы увидите, что конструктор Object
, так как вы спрашиваете у прото f
, который был установлен для объекта {c}
и пропустите прото с o
до f
.
PS: я знаю, что это может быть запутанным объяснением.
PPS: Если вы хотите наследования, придерживайтесь child.prototype = Object.create( parent.prototype ); child.constructor = child;
или класс ES6 class child extends parent
, когда его можно было использовать, лично меня смущало.
var first = function first() {
this.value = 'first function';
};
// before .prototype.extra, first inherist from Function.
console.log( 'constructor of first before:', first.constructor );
first.prototype.extra = 'implemented with .prototype.extra';
// after .prototype.extra, first still inherits from Function, we did not change anything to first itself.
console.log( 'constructor of first after:', first.constructor );
// When first is used as a prototype, the instances will get "extra".
// Aka, everything that inherist from first.
var first_instance = new first();
console.log( 'extra on instance of first:', first_instance.extra );
// f itself does NOT have the extra property, only instances of first do.
console.log( 'extra on first itself:', first.extra );
console.log( '------' );
var second = function second() {
this.value = 'second function';
};
// before setPrototypeOf, second inherist from Function, like above.
console.log( 'constructor of second before:', second.constructor );
Object.setPrototypeOf( second, { extra: 'implemented with .setPrototypeOf()' });
// after setPrototypeOf, second inherist from Object, we broke the default inheritance chain.
console.log( 'constructor of second after:', second.constructor );
// BY doing this, we effectively turned second into an object.
// It no longer is a function, so we cannot use function methods like .call() or .apply()
console.log( 'second is object, not function: function.apply', second.apply );
console.log( 'second is object, not function: object.hasOwnProperty', second.hasOwnProperty );
// When second is used as a prototype, the instances will not get "extra".
var second_instance = new second();
console.log( 'extra on instance of second:', second_instance.extra );
// second itself Does have the extra property, sine we assigned it on the prototype used by second. not when second is used as the prototype.
console.log( 'extra on second itself:', second.extra );