First you need to understand what a prototype is.
In Javascript, almost everything is an object.
Edit (thanks @Mathletics):
Primitive booleans, numbers, and strings are not objects
When you create an object in Javascript, by default, its prototype will be an Object
.
So, if I do:
var obj = {};
console.log(obj.__proto__)
This yields:
Object {}
Pause:
To understand the difference between obj.prototype
and obj.__proto__
, please, refer to this thread.
The next step is to understand the concept of prototype chaining.
This is how inheritance is structured in Javascript. Basically, a prototype is the "parent" of another object, from which it derives methods and properties.
Imagine a scheme where a Rabbit
inherits from Mammal
, which inherits from Animal
. Representing this in Javascript prototype chain would be like:
(Rabbit) -> (Mammal) -> (Animal) -> (Object) -> null
With code:
function Animal(){}
function Mammal(){}
function Rabbit(){}
Mammal.prototype = new Animal();
Rabit.prototype = new Mammal();
If you are able to understand these concepts, you might find the answers to your questions yourself, but I'll try to make it clearer:
1) why one of the following is false and the other is true?
User.prototype.hasOwnProperty('name'); // false
User.hasOwnProperty('name'); // true
You should read the hasOwnProperty
method reference:
Every object descended from Object inherits the hasOwnProperty method. This method can be used to determine whether an object has the specified property as a direct property of that object[...]
This is a way to assure that the property you are looking for is defined within the object itself, not deeper in the prototype chain.
A contrary example would be:
console.log(User.hasOwnProperty('constructor'));
Since the constructor
property is defined deeper in the prototype chaing, it is not an "own property" of User
object.
In your case, name
is a property defined within your User
object, but not defined in the context of the global Object
.
2) what is de difference between the followings:
User.constructor;
User.prototype.constructor;
The fist like takes the constructor of User
, the second takes the constructor of its prototype (in this case, the global Object
).
3) what happens with the User.constructor and
User.prototype.constructor if I override the prototype property like
this:
User.prototype = {
changeName: function(newName) {
this.name = newName;
}
};
Please, read this thread.
TL;DR: when you assing directly to the prototype, you are breaking the prototype chain an creating a new one. In the Rabbit
example, if you at some point did:
Rabbit.prototype = {
// ...
};
Your new prototype chain would be:
(Rabbit) -> (Object) -> null
So, in your first example, User.prototype.constructor
would yield:
function Object{}
In your second example, it would yield:
function User(name)
Got it?
4) is User a function or a prototype or what?
User is an object whose prototype is a Function
object, whose prototype is a Object
object.
Drawing it:
(User) -> (Function) -> (Object) -> null
Hope I've been clear.