Почему свойство прототипа JavaScript не определено для новых объектов?

Я довольно новичок в концепции концепции прототипа JavaScript.

учитывая следующий код :

var x = function func(){
}

x.prototype.log = function() {
  console.log("1");
}

var b = new x();

как я понимаю, b.log() должен возвращать 1 с x является его прототипом. Но почему это свойство b.prototype неопределено?

не b.prototype предполагается вернуть ссылку на

5 ответов


только функции конструктора имеют прототипов. С x является функцией конструктора,x есть прототип.

b - это не функция-конструктор. Следовательно, у него нет прототипа.

если вы хотите получить ссылку на функцию, которая построена b (в данном случае x), вы можете использовать

b.constructor

на .prototype свойство функции существует только для настройки наследования нового объекта при вызове функции в качестве конструктора.

когда новый объект создается, он получает свой внутренний [[Prototype]] собственность определено, что функции .prototype свойство указывает на.

сам объект не получит .prototype собственность. Его отношение к объекту полностью внутреннее.

вот почему это работает b.log(). Когда двигатель JS видит, что b сам объект не имеет log свойство, он пытается найти его на внутренних объектах [[Prototype]]


все обычные объекты в JavaScript имеют внутренний слот прототипа (Примечание: прототип здесь не относится к свойству prototype). Стандарт ECMAScript (http://www.ecma-international.org/ecma-262/6.0/index.html) указывает, что этот слот называется [[прототип]]. Вы можете получить доступ к этому слоту через свойство__ proto__.

свойство__proto__ не может быть надежно доступны в разных браузерах. __прото__ становится официальным собственность в ECMAScript 6

свойство prototype является, однако, свойством функции конструктора, которое задает то, что станет свойством __proto__ на построенном объекте.

вы можете получить доступ к свойству prototype некоторых типов, например, основных типов JavaScript (дата, массив и т. д.). Также функция JavaScript (которую можно рассматривать как конструктор) имеет свойство public prototype. Однако экземпляры функции не имеют свойства prototype.

в случае, var b = new x();, b является экземпляром функции x. Таким образом, b.прототип не определен. Однако b имеет внутренний слот [[прототип]]. Если вы выводите b.__proto__ в Google Chrome, например, версия 63.0.3239.132 или Firefox, например, версия 43.0.4

console.log(b.__proto__);

вы увидите его [[прототип]] слот, как показано ниже:

{log: ƒ, constructor: ƒ}

вот именно.


и только для вашей справки весь фрагмент кода помещается, как показано ниже:

var x = function() {
};
x.prototype.log = function() {
  console.log("1");
}

var b = new x();
b.log();  // 1

console.log(b.prototype); // undefined
console.log(b.__proto__); // {log: ƒ, constructor: ƒ}
console.log(x.prototype); // {log: ƒ, constructor: ƒ}

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

  1. [[prototype]] является скрытым свойством объекта JavaScript.Это скрытое свойство - не что иное, как ссылка на Object.prototype(Если создано объектными литералами).Нет стандартного способа доступа к этому [[prototype]] собственность.
  2. функции в JavaScript являются объектами, поэтому они также имеют [[prototype]] собственность.Здесь, в случае функции это скрыто свойство является ссылкой на Function.prototype.Также нет стандартного способа доступа к этому [[prototype]] собственность.
  3. кроме этой скрытой ссылки [[prototype]], всякий раз, когда создается объект функции, a prototype в нем создается свойство, которое отделено от hidden [[prototype]] собственность.

сейчас в коде :

var x = функция func () {}

когда эта строка выполняется, объект функции x создается с двумя ссылками :


    , потому что prototype является свойством функций (фактически, конструкторов), так как определяет свойства/методы объектов этого класса (те, которые были созданы из конструктора, которому принадлежит этот прототип). Взгляните на этой ссылке