Подтвердить что ты не робот

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

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

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

var x = function func(){
}

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

var b = new x();

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

Не предполагается ли b.prototype вернуть ссылку на функцию x?

4b9b3361

Ответ 1

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

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

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

b.constructor

Ответ 2

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

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

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

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

Чтобы быть ясным, свойство [[Prototype]] не доступно напрямую. Это внутреннее свойство, которое только косвенно изменено с помощью других конструкций, предоставляемых механизмом JS.

Ответ 3

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

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

Теперь переходим к вашему коду:

var x = function func() {}

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

  • Функция.прототип (недоступен),
  • x.prototype(доступно).

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

как мы теперь знаем, x - это объект функции, поэтому x.prototype доступен, поэтому здесь вы можете включить с ним метод журнала.

var b = new x();

b - объект, но не объект функции. У него есть скрытая ссылка [[prototype]], но она недоступна. поэтому, когда вы пытаетесь получить доступ, как b.prototype, он дает undefined в качестве результата. Если вы хотите проверить прототип b, чем вы видите (x.prototype).isPrototypeOf(b);, он вернет true. поэтому вы можете сказать, что скрытая ссылка ссылается на x.prototype.

Вот некоторые факты о прототипе:

  • Если объект O создан с помощью O = new func(){}, чем O [[prototype]] равен Function.prototype.
  • Если объект O создается с помощью O = {}, чем O [[prototype]], это Object.prototype.
  • Если объект O создан с помощью O = Object.create(obj), чем O [[prototype]], это obj.

Ответ 4

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

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

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

В вашем случае b.prototype - undefined, но если вы выходите в Firefox, например версии 43.0.4

console.log(b.__proto__);

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

func { log=function()}

Ответ 5

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