Сначала вы должны понять, что прототип есть.
В Javascript, почти все это объект.
Edit (спасибо @Mathletics):
Примитивные BOOLEANS, числа и строки не являются объектами
При создании объекта в Javascript, по умолчанию, его прототип будет Object
.
Так что, если я делаю:
var obj = {};
console.log(obj.__proto__)
Это дает:
Object {}
Пауза:
Чтобы понять разницу между obj.prototype
и obj.__proto__
, пожалуйста, обратитесь к этому thread.
Следующий шаг заключается в понимании концепции prototype chaining.
Вот как наследование структурировано в Javascript. В принципе, прототип является «родителем» другого объекта, из которого он выводит методы и свойства.
Представьте схему, в которой Rabbit
наследует от Mammal
, который наследует от Animal
.Представляя это в Javascript цепи прототипов будет, как:
(Rabbit) -> (Mammal) -> (Animal) -> (Object) -> null
С кодом:
function Animal(){}
function Mammal(){}
function Rabbit(){}
Mammal.prototype = new Animal();
Rabit.prototype = new Mammal();
Если вы в состоянии понять эти концепции, вы можете найти ответы на свои вопросы самостоятельно, но я попробуйте уточнить:
1) почему одно из следующих является ложным, а другое верно?
User.prototype.hasOwnProperty('name'); // false
User.hasOwnProperty('name'); // true
Вы должны прочитать hasOwnProperty
method reference:
Каждый объект происходит от объекта наследует метод hasOwnProperty. Этот метод может быть использован для определения того, имеет ли объект указанное свойство как прямое свойство этого объекта [...]
Это способ гарантировать, что свойство, которое вы ищете, определено внутри объекта а не глубже в цепи прототипов.
Противоположный пример будет:
console.log(User.hasOwnProperty('constructor'));
Поскольку свойство constructor
определяется глубже в прототипе Chaing, это не является «собственностью» из User
объекта.
В вашем случае name
является свойством, определенным в вашем User
объекте, но не определяемом в контексте глобального Object
.
2), что де разница между следующим:
User.constructor;
User.prototype.constructor;
Кулаком нравится принимает конструктор User
, второй принимает конструктор своего прототипа (в данном случае глобальной Object
).
3), что происходит с User.constructor и User.prototype.constructor если переопределить свойство прототипа как этого:
User.prototype = {
changeName: function(newName) {
this.name = newName;
}
};
Пожалуйста, прочитайте эту thread.
TL; DR: когда вы непосредственно передаете прототип, вы нарушаете цепочку прототипов, создавая новую.В Rabbit
Например, если вы в какой-то момент сделал:
Rabbit.prototype = {
// ...
};
Ваш новый прототип цепи будет:
(Rabbit) -> (Object) -> null
Так, в первом примере, User.prototype.constructor
даст:
функция Объект {}
В вашем втором ex достаточно, это даст:
Функция пользователя (имя)
Понял?
4) Пользователь является функцией или прототипом или что?
Пользователь объект прототипом которого является Function
объекта, прототипом которого является Object
объектом.
Рисунок это:
(User) -> (Function) -> (Object) -> null
Надежда Я ясно.
Возможный дубликат [Как работает JavaScript .prototype?] (Http://stackoverflow.com/questions/572897/how-does-javascript-prototype-work) – Mathletics