there are two ways to define a constructor with basic data:
var Person1 = function() {
this.name = "Wayne";
};
var Person2 = function() {};
Person2.prototype.name = "Wayne";
whats the difference between that?
there are two ways to define a constructor with basic data:
var Person1 = function() {
this.name = "Wayne";
};
var Person2 = function() {};
Person2.prototype.name = "Wayne";
whats the difference between that?
Whats the difference between that?
With a string or other primitive, there isn't a huge difference, but with the first one each instance gets its own name
property with the value "Wayne"
; with the second, there's only one name
property, on the prototype, and it has the value "Wayne"
.
ASCII-art can help here, suppose we have:
var p1 = new Person();
var p2 = new Person();
var p3 = new Person();
With your first code, we get this:
+-----------------+ +-----------------+ +-----------------+ | p1 | | p2 | | p3 | +-----------------+ +-----------------+ +-----------------+ | __proto__ |---+ | __proto__ |---+ | __proto__ |---+ | name: "Wayne" | | | name: "Wayne" | | | name: "Wayne" | | +-----------------+ | +-----------------+ | +-----------------+ | | | | | +---------------------+ | | | | | +----------------------------------------------+ | | +------------------+ +--+->| Person.prototype | +------------------+ | | +------------------+
With your second code, using the prototype, we get this:
+-----------------+ +-----------------+ +-----------------+ | p1 | | p2 | | p3 | +-----------------+ +-----------------+ +-----------------+ | __proto__ |---+ | __proto__ |---+ | __proto__ |---+ +-----------------+ | +-----------------+ | +-----------------+ | | | | | +---------------------+ | | | | | +----------------------------------------------+ | | +------------------+ +--+->| Person.prototype | +------------------+ | name: "Wayne" | +------------------+
It's important to note, though, that when you do this:
p1.name = "Greyson";
...that does not change Person.prototype.name
(in the normal case); it gives p1
its own name
property, giving us this:
+-----------------+ +-----------------+ +-----------------+ | p1 | | p2 | | p3 | +-----------------+ +-----------------+ +-----------------+ | __proto__ |---+ | __proto__ |---+ | __proto__ |---+ | name: "Greyson" | | +-----------------+ | +-----------------+ | +-----------------+ | | | | | | | +---------------------+ | | | | | +----------------------------------------------+ | | +------------------+ +--+->| Person.prototype | +------------------+ | name: "Wayne" | +------------------+
It's an assymetric process: When you write to a property, in the normal case, it creates or updates one on the actual object you're using; but when you read from a property, it looks first at that object to see if it has it, and if it doesn't it goes to the object's prototype object, then to that object's prototype object, etc. as necessary. So when you try to use name
's value later:
console.log(p1.name);
console.log(p2.name);
console.log(p3.name);
...the JavaScript engine looks first at the instance (the p1
, p2
, or p3
) to see if it has the property and uses that property's value if it does; if the instance doesn't, the engine looks at the prototype, and uses the property there if it has it.
I say "in the normal case" above because properties can have getters and setters, which can change how this works. I won't go into it here, just flagging it up.