#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. ДА. И не рекомендуется, ни много ни мало. 😉