3

I am new to JavaScript, but not to OOP in general.

Is this a valid way of creating getters & setters in JavaScript?

The "class",

function Person (age){
    this.age = age;
};

Getter,

Person.prototype.getAge = function(){
    return this.age;
};

and a setter.

Person.prototype.setAge = function(arg){
    this.age = arg;
};

It seems to work fine, but I dont know the convention, I get diffrent descriptions everywhere, but is my solution valid?

timpal0l
  • 63
  • 1
  • 5
  • See this link http://ejohn.org/blog/javascript-getters-and-setters/ – Shreyos Adikari Apr 17 '14 at 01:28
  • A side note for you to not confuse with similar terms: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Defining_getters_and_setters – zerkms Apr 17 '14 at 01:28

1 Answers1

2

You probably want Object.defineProperty (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty), here's an example of it in use:

Object.defineProperty(Person.prototype, 'age', {
  get: function(){
    return this.__age__;
  },
  set: function(value){
    this.__age__ = value;
  }
});

You can also hold a variable somewhere else if you want. The following would act as a singleton value that is set and accessed across all instances of Person:

var age;

Object.defineProperty(Person.prototype, 'age', {
  get: function(){
    return age;
  },
  set: function(value){
    age = value;
  }
});

If you want an age variable for every instance of the Person objects you create, you need to add the variable declaration inside your constructor:

function Person(){
  var age; 
  // ditto from the second example
}
csuwldcat
  • 8,021
  • 2
  • 37
  • 32
  • 3
    `this.______________age______________` -- a very-very-very private member – zerkms Apr 17 '14 at 01:34
  • @zerkms double underbars are the unspoken private flag for properties (even browsers have used the convention) – csuwldcat Apr 17 '14 at 01:36
  • So what will the practical differences be between our solutions? – timpal0l Apr 17 '14 at 01:38
  • @timpal0l: the difference is semantical. Your solution is more obvious, the given is more magical. – zerkms Apr 17 '14 at 01:39
  • 1
    @csuwldcat: any reference for `__foo__` code conventions? I've seen the `_foo` or `foo_` are used more frequently. – zerkms Apr 17 '14 at 01:44
  • @zerkms there are quite a few, for instance `__proto__` and the old set/get functions `__defineGetter__`/`__defineSetter__`. The browsers themselves have a few in their non-exposed interfaces. (I worked for Mozilla for 5 years) – csuwldcat Apr 17 '14 at 01:45
  • @csuwldcat: well, too few to become a convention though :-) – zerkms Apr 17 '14 at 01:45
  • @zerkms take a look at the chrome JS DOM of Firefox and other browsers, you'll find many, many more ;) – csuwldcat Apr 17 '14 at 01:48
  • *"If you want an age variable for every instance of the Person objects you create, you need to add the variable declaration inside your constructor"* But then you can't make use of prototype methods anymore. – Felix Kling Apr 17 '14 at 01:59
  • @FelixKling can you elaborate a bit? I'm not sure what you mean, a variable inside a constructed object should not have any affect on the ability to modify the prototype - can you clarify? – csuwldcat Apr 17 '14 at 02:02
  • @zerkms, you make me smile <3 – Mulan Apr 17 '14 at 02:02
  • I mean, you can't use that variable in methods added to the prototype. You'd have to create those methods inside the constructor, which is generally not such a great idea. – Felix Kling Apr 17 '14 at 02:04
  • @Felix Kling: there is accessor for that. Not to discuss it's a bad idea but just not "can't use" – zerkms Apr 17 '14 at 02:05
  • @zerkms, re: your "very private var" comment – Mulan Apr 17 '14 at 02:05
  • If the other prototype methods are added outside of the constructor's scope (outside the constructor function body, after it is created), `age` will not hold the same value - know what I mean? – csuwldcat Apr 17 '14 at 02:07
  • @zerkms: Not sure what you mean. There are workarounds to get this work somehow, but they all add too much boilerplate code IMO. When we get Symbols, things look better :) – Felix Kling Apr 17 '14 at 02:07
  • @Felix Kling: what I meant: "you can't use that variable in methods added to the prototype" --- you can use setter to modify it, and getter to retrieve its value. It's not "not possible" – zerkms Apr 17 '14 at 02:08
  • @zerkms: You mean adding the getter and setter in the constructor function? Sure, but that goes in the direction of *"You'd have to create those methods inside the constructor, which is generally not such a great idea"*. Maybe I wasn't clear enough: Directly accessing the "private" variable is not possible in prototype methods, hence it looses a bit of its appeal. It looks like though that I missed the `// ditto from the second example` comment in the last example. – Felix Kling Apr 17 '14 at 02:10
  • @Felix Kling: yep. Btw, technically one may define them in a scoped function thus have it declared once. – zerkms Apr 17 '14 at 02:12
  • @csuwldcat: Looks like I missed your `// ditto from the second example` comment in the last example. I personally just don't think that this approach is a good idea in general because it has drawbacks. – Felix Kling Apr 17 '14 at 02:12
  • @FelixKling that said, the majority of use-cases for setters/getters are not concerned with accessing the private var directly, they are for holding some var (private or otherwise) and doing some other logic when the set/get occurs. The 'concern' you speak of seems like a red herring to me. – csuwldcat Apr 17 '14 at 02:12
  • @csuwldcat: Sure, getters and setters make sense. I'm just sensitive when someone "casually" mentions to use `var x` to simulate private properties, without explaining or at least referring to its drawbacks. Devs less familiar with JS can easily be let on the wrong path by that. If you think getters and setters aren't actually related to visibility that much, I would not even mention it. Anyways, I stated my opinion, nothing left for me to do here. – Felix Kling Apr 17 '14 at 02:18