Reputation: 2185
i'm working with a piece of code that sets a name property as a function
name = n;
this.name = function(n){
if( n ) name=n;
return name;
}
full constructor is:
function Warrior(n){
name = n;
this.name = function(n){
if( n ) name=n;
return name;
}
}
I don't understand how this is different than this.name = n; and why I can't use that in a toString function like
Person.prototype.toString = function(){
return "Hi! my name's "+this.name;
}
Upvotes: 1
Views: 119
Reputation: 74244
What you created is a getter/setter for name
:
Getters and setters are useful for creating “derived properties” (i.e. properties which are derived from other properties). For example:
function Person(firstname, lastname) {
this.firstname = firstname;
this.lastname = lastname;
}
Person.prototype.fullname = function (fullname) {
if (arguments.length < 1) return this.firstname + " " + this.lastname;
var newname = fullname.split(" ");
this.firstname = newname[0];
this.lastname = newname[1];
return fullname;
};
var person = new Person("Aadit", "Shah");
alert(person.firstname);
alert(person.lastname);
alert(person.fullname());
person.fullname("Chuck Norris");
alert(person.firstname);
alert(person.lastname);
alert(person.fullname());
In the above code fullname
is a derived property. It is derived from firstname
and lastname
. As you can see, when I update fullname
, I am also updating firstname
and lastname
. Hence getters and setters are useful in this case.
However a lot of people misuse getters and setters. For example:
function Warrior(name) {
this.name = function (newName) {
if (arguments.length >= 1)
name = newName;
return name;
}
}
In this case there's no good reason to create a getter/setter for name because it is not a derived property. It's a misuse of getters/setters and all it does is make the code slower. Instead it should be implemented as:
function Warrior(name) {
this.name = name;
}
Plain and simple.
Now consider:
Person.prototype.toString = function () {
return "Hi! my name's " + this.name;
};
The reason this doesn't work is because this.name
is a getter function. Hence you need to call it to get the actual value. Thus, it should be:
Person.prototype.toString = function () {
return "Hi! my name's " + this.name();
};
Finally, newer versions of JavaScript have built in support for getters and setters:
function Person(firstname, lastname) {
this.firstname = firstname;
this.lastname = lastname;
}
Object.defineProperty(Person.prototype, "fullname", {
get: function () {
return this.firstname + " " + this.lastname;
},
set: function (fullname) {
var newname = fullname.split(" ");
this.firstname = newname[0];
this.lastname = newname[1];
}
});
var person = new Person("Aadit", "Shah");
alert(person.firstname);
alert(person.lastname);
alert(person.fullname);
person.fullname = "Chuck Norris";
alert(person.firstname);
alert(person.lastname);
alert(person.fullname);
This makes getters and setters look like normal properties. Such properties are called accessor properties.
Upvotes: 1
Reputation: 1668
Here your constructor function is Warrior
and you can add new method toString
to an existing prototype Warrior
. Like this you can add.
Warrior.prototype.toString = function(){ // code goes here }
this.name
is a function .so
Warrior.prototype.toString = function(){
return "Hi! my name's "+this.name();
}
Using new
keyword to create new objects from the same prototype
Warrior.prototype.toString = function(){
return "Hi! my name's "+this.name();
}
myname = new Warrior("ur name");
console(myname.toString());
Upvotes: 0