elepil
asked on
How to create Accessor methods (getter/setter) with my constructor
I know how to define getter/setters with in object literal mode, e.g.:
What I'd like to know is how to make a getter/setter on this following constructor. Thanks.
var person = {
...
get firstName() {
return firstName;
},
set firstName(value) {
firstName = value;
}
...
}
What I'd like to know is how to make a getter/setter on this following constructor. Thanks.
function Person(firstName, lastName) {
/**
* Private properties and methods
*/
var _firstName = firstName == undefined ? "" : firstName; // private
var _lastName = lastName == undefined ? "" : lastName; // private
var initials = function(_firstName, _lastName) { // private
return _firstName.substr(0,1) + " " + _lastName.substr(0,1);
};
/**
* Public properties and methods
*/
this.firstName = _firstName; // [How do turn firstName and lastName into getters/setters?]
this.lastName = _lastName;
this.toString = function() {
return firstName + " " + lastName;
};
this.toStringInitials = function() {
return initials(_firstName, _lastName);
};
};
var p = new Person("John", "Doe");
var p2 = new Person("Jane", "Dopey");
function Person(firstName, lastName) {
/**
* Private properties and methods
*/
var _firstName = firstName == undefined ? "" : firstName; // private
var _lastName = lastName == undefined ? "" : lastName; // private
var initials = function(_firstName, _lastName) { // private
return _firstName.substr(0,1) + " " + _lastName.substr(0,1);
};
/**
* Public properties and methods
*/
this.getFirstName = function (){
return _firstName;
}
this.getLastName = function (){
return _lastName;
}
this.setFirstName = function (firstName){
_firstName = firstName;
}
this.setLastName = function (lastName){
_lastName = lastName;
}
this.toString = function() {
return _firstName + " " + _lastName;
};
this.toStringInitials = function() {
return initials(_firstName, _lastName);
};
};
var p = new Person("John", "Doe");
var p2 = new Person("Jane", "Dopey");
p.getFirstName()
"John"
p.setFirstName("Sally")
p.getFirstName()
"Sally"
ASKER
Kyle, thanks for responding.
I knew how to create getter and setter functions the way you did, and as much as it works, it is not "true-to-form" to JavaScript getters/setters and is not what I was looking for.
If you look at my original post at the very top, I actually gave a sample of get/set syntax in object literal mode. The 'get' and 'set' you see are actual keywords in JavaScript. What I wanted to know was how to define, using the Javascript get/set keywords, in NON-object literal mode (in this case, a function).
Thanks.
I knew how to create getter and setter functions the way you did, and as much as it works, it is not "true-to-form" to JavaScript getters/setters and is not what I was looking for.
If you look at my original post at the very top, I actually gave a sample of get/set syntax in object literal mode. The 'get' and 'set' you see are actual keywords in JavaScript. What I wanted to know was how to define, using the Javascript get/set keywords, in NON-object literal mode (in this case, a function).
Thanks.
not sure what you mean by "not-true-to-form". That is the way public methods are written in javascript.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Defining_Getters_and_Setters
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Defining_Getters_and_Setters
You might want to have a look at this article as well, which describes some getter/setter syntaxes:
http://whereswalden.com/2010/04/16/more-spidermonkey-changes-ancient-esoteric-very-rarely-used-syntax-for-creating-getters-and-setters-is-being-removed/
http://whereswalden.com/2010/04/16/more-spidermonkey-changes-ancient-esoteric-very-rarely-used-syntax-for-creating-getters-and-setters-is-being-removed/
ASKER
Kyle, what I meant by "not-true-to-form" is that you used "getFirstName/setFirstName " instead of the JavaScript keywords get and set. I was trying to create a getter/setter using those keywords because they have the added advantage of being able to access the property without seeing the words get and set. For example, if you defined the following in object literal form:
var Person = {
_firstName: "John",
get firstName () {
return "First Name";
},
set firstName(value) {
_firstName = value;
}
}
You would access the firstName property as:
var p = Person();
console.log(p.firstName);
But the way you did it was define functions called getFirstName and setFirstName. That means, to access them, you'd have to say:
var p = Person();
console.log(p.getFirstName);
Do you see the distinction I am making? You did it the Java way, which is the way I'd do it in Java, too. But certain languages like Actionscript and JavaScript have the get/set constructs especially designed for getter/setters that Java doesn't have.
var Person = {
_firstName: "John",
get firstName () {
return "First Name";
},
set firstName(value) {
_firstName = value;
}
}
You would access the firstName property as:
var p = Person();
console.log(p.firstName);
But the way you did it was define functions called getFirstName and setFirstName. That means, to access them, you'd have to say:
var p = Person();
console.log(p.getFirstName);
Do you see the distinction I am making? You did it the Java way, which is the way I'd do it in Java, too. But certain languages like Actionscript and JavaScript have the get/set constructs especially designed for getter/setters that Java doesn't have.
I hear you. I just don't think those keywords are available for functions. Though I'm sure you could do some fancy shenanigans to extend your functions with ObjectProperties or some other construct. I think it will make the code unreadable without bringing any real advantage.
If you want to use p.firstName, then you might as well write this.firstName = firstName; Making first name and last name private doesn't give you much if you are going to offer public setters for them. If you are concerned about encapsulation, any processing of first and last name can still be done in the Person object without the need for your library users to know anything about it.
If you look over the the second link I posted, the syntax you would like to use is not "recommended".
I would write it like this, since for me, it's a lot easier to read and maintain, but that is just a personal preference. I hate arguing about coding. You are welcome to "request attention" to get more eyes on this.
If you want to use p.firstName, then you might as well write this.firstName = firstName; Making first name and last name private doesn't give you much if you are going to offer public setters for them. If you are concerned about encapsulation, any processing of first and last name can still be done in the Person object without the need for your library users to know anything about it.
If you look over the the second link I posted, the syntax you would like to use is not "recommended".
I would write it like this, since for me, it's a lot easier to read and maintain, but that is just a personal preference. I hate arguing about coding. You are welcome to "request attention" to get more eyes on this.
function Person(firstName, lastName) {
this.firstName = firstName == undefined ? "" : firstName;
this.lastName = lastName == undefined ? "" : lastName;
var initials = function() { // private
return this.firstName.substr(0,1) + " " + this.lastName.substr(0,1);
};
this.toString = function() {
return this.firstName + " " + this.lastName;
};
this.toStringInitials = function() {
return initials();
};
};
hey, I tried and tried to get the p.firstName to be an Object reference for an Object that has the
get firstName()
but I could not do it, after failing for many different tries, I believe (for me anyway) to use an OO and have both names (first, last) in a names object, Not really a solution, but a workable to have an interactive (many values in function object changed) by simply assigning a value (no function call);
get firstName()
but I could not do it, after failing for many different tries, I believe (for me anyway) to use an OO and have both names (first, last) in a names object, Not really a solution, but a workable to have an interactive (many values in function object changed) by simply assigning a value (no function call);
function Person2(firstName1, lastName1) {
/* Private properties and methods */
var _firstName = firstName1 == undefined ? "" : firstName1; // private
var _lastName = lastName1 == undefined ? "" : lastName1; // private
var initials = function(_firstName, _lastName) { // private
return _firstName.substr(0,1) + " " + _lastName.substr(0,1);
};
this.names = {count:1, // object
get first() {
return _firstName;
},
set first(value) {
this.count++;
_firstName = value+this.count;
},
get last() {
return _lastName;
},
set last(value) {
this.count++;
_lastName = value+this.count;
}
};
this.toString = function() {
return _firstName + " " + _lastName;
};
this.toStringInitials = function() {
return initials(_firstName, _lastName);
};
};
var p = new Person2("KILohn", "DoeJoke");
p.names.first = "New Name";
p.names.last = "How IT";
document.write("Names = "+p.names.first+" - "+p.names.last);
Just a way, but the functions are different than the objects for containing some operations.
@Slick812,
What advantage does this offer? Why are we trying to force the get set keywords?
Why is p.names.first better than p.getFirstName ?
I'm not being a jerk, I really would like to know what the benefit is.
The comments in this Ajaxian article are also pretty mixed:
http://ajaxian.com/archives/getters-and-setters-in-javascript
What advantage does this offer? Why are we trying to force the get set keywords?
Why is p.names.first better than p.getFirstName ?
I'm not being a jerk, I really would like to know what the benefit is.
The comments in this Ajaxian article are also pretty mixed:
http://ajaxian.com/archives/getters-and-setters-in-javascript
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Kyle,
The this.firstName = firstName, while it works, would not be using getters/setters. The reason why that is important to me is because my application will very possibly need to throw an event when a property value is changed so that those that are listening can react accordingly, and that's not possible if you don't set up a setter function.
Maybe you're right, that there's no way to use the get/set keywords in a function. I'm new to this, and that's why I created this post, to try to learn from those more experienced than I am like yourself. I hate using the Object.defineProperty because the sequence of code becomes bizarre where I'd have to instantiate an object first, and then apply Object.defineProperty for each of the properties. I have experimental code that tells me this has its own problems as well. I guess I just want to implement OOP and still keep things simple (as in Java, C#, etc.), and that is getting to be problematic with JavaScript.
The this.firstName = firstName, while it works, would not be using getters/setters. The reason why that is important to me is because my application will very possibly need to throw an event when a property value is changed so that those that are listening can react accordingly, and that's not possible if you don't set up a setter function.
Maybe you're right, that there's no way to use the get/set keywords in a function. I'm new to this, and that's why I created this post, to try to learn from those more experienced than I am like yourself. I hate using the Object.defineProperty because the sequence of code becomes bizarre where I'd have to instantiate an object first, and then apply Object.defineProperty for each of the properties. I have experimental code that tells me this has its own problems as well. I guess I just want to implement OOP and still keep things simple (as in Java, C#, etc.), and that is getting to be problematic with JavaScript.
having said that, I'm still not sure about the wisdom of doing this.
The user of your library may get unexpected results if you process their values. I would expect that when I set Field.value, that value will not be changed. This is along the lines of modifying native functionality, for example messing with Object.prototype
I still think it is a lot clearer to provide explicit getter or setter methods. no confusion.
The user of your library may get unexpected results if you process their values. I would expect that when I set Field.value, that value will not be changed. This is along the lines of modifying native functionality, for example messing with Object.prototype
I still think it is a lot clearer to provide explicit getter or setter methods. no confusion.
Hi elepil, maybe we posted at the same time. did you see the John Resig example above?
correction to above post:
var v = new Field();
v.value = "whatever"
console.log(v.value);
correction to above post:
var v = new Field();
v.value = "whatever"
console.log(v.value);
ASKER
You did it, Kyle! Your solution is the only one that meets all criteria of a typical OOP object as we know with languages such as Java, C#, etc. Here's a more elaborate code sample expounding on your solution:
As far as I can tell, your solution provides the ability to simulate the creation of an OOP data model as used with languages like Java, C#, etc.
It allows definition of private and public properties/methods, as well as providing definition of properties by way of getters/setters.
Thanks for your help!
function Person(firstName, lastName, gender){
/**
* Private properties and methods
*/
var _firstName = firstName; // private property
var _lastName = lastName; // private property
var _initials = function() { // private method
return _firstName.substr(0,1) + " " + _lastName.substr(0,1);
}
/**
* Public properties and methods
*/
this.gender = gender; // public
// public getter/setters for firstName and lastName
this.__defineGetter__("firstName", function(){
return _firstName;
});
this.__defineSetter__("firstName", function(value){
_firstName = value;
});
this.__defineGetter__("lastName", function() {
return _lastName;
});
this.__defineSetter__("lastName", function(value) {
_lastName = value;
})
// Public methods
this.toString = function() {
return _firstName + " " + _lastName;
}
this.toStringInitials = function() {
return _initials();
}
}
var p1 = new Person("John", "Doe", "M");
var p2 = new Person("Jane", "Bimbo", "F");
console.log(p1.firstName);
console.log(p2.lastName);
console.log(p1.toString());
console.log(p2.toStringInitials());
As far as I can tell, your solution provides the ability to simulate the creation of an OOP data model as used with languages like Java, C#, etc.
It allows definition of private and public properties/methods, as well as providing definition of properties by way of getters/setters.
Thanks for your help!
ASKER
Excellent, Kyle, nailed it!! Many thanks for your help!
:)
ASKER