Reputation: 8695
Consider the following little bit of JavaScript: (I'm not worried about backward compatibility and I don't want to use anything that will soon be deprecated).
var Person = (function () {
var _age,
_name;
function age(num) {
if (!num) {
return _age;
}
else {
_age = num;
}
}
function name(val) {
if (!val) {
return _age;
}
else {
_name = val;
}
}
return {
age: age,
name: name
}
})();
console.log(Person.age()); //undefined
Person.age(100);
console.log(Person.age()); //100
(not sure how useful this will be, if I wanted to do something polymorphic the prototype here is still Object.)
vs. (constructor inside iffy, closure allows name and val accecss to _name and _val
var Person = (function () {
var _age,
_name;
function Person(options) {
_age = options.age;
_name = options.name;
}
Person.prototype.age = function (val) {
if (!val) {
return _age;
}
else {
_age = val;
}
}
var test = new Person({ age: 100, name: 'jon' });
console.log(test.age());//100
//if I want to do with Person objects outside of this script I should
//return something
})();
(this allows for the standard property styles I'm looking for (a null parameter return a value and passing a parameter will set that value
function Person(age, name) {
//i don't want to add get and set methods to each instance of Person
}
Person.prototype.age = function (num) {
if (!num) {
//what to return if nothing is passed to age?
return //what?
}
else {
//x = num
//what would x be?
}
}
I need to be able to perform some actions polymorphically based on the prototype. The last code snippet is the easiest to read, but it doesn't offer the get/set succintness I'm looking for. The first code snippet will let me Object.create
nicely enough but it has Object as the prototype. If I want get/set methods like obj.test()
to get and obj.test(100)
to set, how can I achieve this adding methods to the prototype and not inside the constructor itself?
Upvotes: 2
Views: 1513
Reputation: 29941
Not directly related to your question, but since you mentioned "getters and setters" on your title, I thought I might complement the answers with ES5 getters and setters:
function Person(age, name) {
this.name = name;
this.age = age;
};
Object.defineProperty(Person.prototype, "age", {
get: function() {
return this._age;
},
// Added a few things to demonstrate additional logic on the setter
set: function(num) {
num = parseInt(num, 10);
if(num > 0) {
this._age = num;
}
}
});
Then, it can be used transparently, as if it was a normal property:
var person = new Person(20, "Jane Doe");
person.age; // => 20
person.age = 15;
person.age; // => 15
person.age = "20";
person.age; // => 20 (number)
person.age = -2;
person.age; // => 20
Works on any recent browser, and IE >= 9.
Upvotes: 5
Reputation: 190897
You will have to store it as a public property on your instance. The commonly used convention is to use _
as denoting as a private member.
Here is an implementation for you.
function Person(age, name) {
this.age(age);
}
Person.prototype.age = function (num) {
if (!num) {
return this._age;
}
else {
this._age = num;
}
}
Upvotes: 2