Для чего используется свойство прототипа JS-функции?

#javascript #prototypal-inheritance

#javascript #прототипирование-наследование

Вопрос:

Я понимаю наследование прототипа javascript через __proto__ свойство. Однако я замечаю, что при выполнении var f = function() {} у f теперь будет prototype свойство в дополнение к __proto__ свойству. Казалось бы, prototype это не участвует в цепочке свойств. Что именно это делает?

Комментарии:

1. Когда вы вызываете функцию как конструктор, __proto__ свойство возвращаемого объекта ссылается на prototype объект функции.

Ответ №1:

Оно назначается в качестве прототипа объектов, созданных с помощью этой функции с помощью new ключевого слова.

Так, например:

 function Foo() {
}
Foo.prototype.bar = 47;

var obj = new Foo();
alert(obj.bar); // alerts 47, via `obj`'s prototype
  

Ссылка между obj и объектом, назначенным Foo.prototype , является действующей, и поэтому добавление дополнительных элементов к Foo.prototype заставит их отображаться в obj прототипе:

 Foo.prototype.charlie = 62;
alert(obj.charlie); // alerts 62
  

Естественно, если вы замените Foo.prototype (что я не одобряю), то вы указываете Foo.prototype на другой объект. obj все равно будет ссылаться на старое:

 Foo.prototype = {delta: 77}; // Not recommended
alert(obj.delta); // alerts "undefined"
  

Бесплатный живой пример

Что касается __proto__ : __proto__ является нестандартным. До ECMAScript5 (которому всего полтора года) не было никакого стандартного способа прямого взаимодействия с прототипом объекта, вы могли назначать их только во время создания объекта и только косвенно через prototype свойство функции-конструктора. __proto__ является проприетарным расширением в некоторых движках JavaScript (в первую очередь в Mozilla SpiderMonkey, движке Firefox). Этого нет ни в одном стандарте, и, согласно комитету ECMAScript, этого не будет. (Вместо этого ECMAScript5 предоставляет функции для взаимодействия с прототипом объекта.) __proto__ В настоящее время не рекомендуется Mozilla.

Ответ №2:

_proto_ свойство является свойством экземпляра объекта (объектом в данном случае является функция), оно ссылается на прототип экземпляра. Следует отметить, что это свойство является нестандартным и устаревшим, используйте Object.getPrototypeOf(ref) вместо этого: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/Proto

prototype в отличие от этого, является свойством объявления функции (не экземпляра) и прототипом для всех экземпляров функции. Ознакомьтесь с документами:https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/prototype

Когда вы создаете новый экземпляр функции (используя new ключевое слово), создается объект function, как определено prototype . После создания экземпляра ( var myNewObject = new Foo() ) вызов Object.getPrototypeOf(myNewObject) возвращает ссылку на прототип, на котором основан экземпляр.

Подводя итог: __proto__ это то, чем что-то является, prototype это то, чем что-то МОЖЕТ БЫТЬ (или уже может быть).

Комментарии:

1. » _proto_ свойство является свойством экземпляра функции» Экземпляра объекта (который может быть создан функцией, а может и не быть).

2. Справедливо, это все еще нестандартно 🙂

3. ДА. И не рекомендуется, ни много ни мало. 😉