Getters and setters with JavaScript – code samples and demos

Not many people know it, but you can use “real” getters and setters in JavaScript if you want to.

De-facto offerings

Firefox 2.0+, Safari 3.0+, Google Chrome 1.0+ and Opera 9.5+ support a de-facto way of getters and setters:

var lost = {
	loc : "Island",
	get location () {
		return this.loc;
	},
	set location(val) {
		this.loc = val;
	}
};
lost.location = "Another island";

// lost.location will now return "Another island"

And on DOM elements:

HTMLElement.prototype.__defineGetter__("description", function () {
	return this.desc;
});
HTMLElement.prototype.__defineSetter__("description", function (val) {
	this.desc = val;
});
document.body.description = "Beautiful body";

// document.body.description will now return "Beautiful body";

Via Object.defineProperty

The future, and ECMAScript standardized way, of extending objects in all sorts of ways is through Object.defineProperty. This is how Internet Explorer chose to implement getters and setters, but it is unfortunately so far only available in Internet Explorer 8, and not in any other web browser. Also, IE 8 only supports it on DOM nodes, but future versions are planned to support it on JavaScript objects as well.

Getter and setters in IE8+:

Object.defineProperty(document.body, "description", {
	get : function () {
		return this.desc;
	},
	set : function (val) {
		this.desc = val;
	}
});
document.body.description = "Content container";

// document.body.description will now return "Content container"

Test cases

I’ve put together test cases in my JavaScript test site, where you can see JavaScript web browser compatibility tables and code samples and demos for getters and setters together with Object.defineProperty.

Conclusion

Kudos for Microsoft to take the step to implement Object.defineProperty, although it’s sad that it’s only available for DOM elements as of now. Also, just as we have consistency between web browsers with innerHTML, XMLHTTPRequest etc, it would have been really desirable if Microsoft would have supported the several years-old de-facto way of implementing getters and setters.

So, Microsoft slowly treads forward, which is good, but at the same unfortunately gives us yet another case of doing something different to make it work in Internet Explorer (more about this can be read in ECMAScript getters and setters interoperability).

Anyway, getters and setters are here today, and with some feature detection, you can use it to implement some nice things. Happy coding! :-)

20 Comments

  • #1 Andrea Giammarchi
    May 28th, 2009 at 21:20

    Hi Robert, it is not only DOM, it is the global Window object as well ;-)

    In any case, since other browsers implements define[G|S]etter since ages, it is possible to replicate both behaviors normalizing a bit the panorama.

    Regards

  • #2 Robert Nyman - author
    May 28th, 2009 at 22:58

    Andrea,

    Good point about the <code>window</code>. :-)

    Nice concept, one can definitely normalize the usage of it. Here, I just wanted to present the concept and let people know about what we have to deal with.

  • #3 Henrik Hjelte
    May 29th, 2009 at 18:19

    Syntactic sugar. Not backwards compatible. Why keep making the language bigger with meaningless things like this? If this continues one day we will wake up and discover that Javascript is not the small flexible language anymore, it is bloated and the pocket reference doesn't fit into the pocket anymore. Please stop.

  • #4 Richard
    May 29th, 2009 at 19:04

    One thing to keep in mind when using this. It should be only be used for encapsulation inside of an object. Meaning if you need to access a variable inside another js "object" then use this. Otherwise it is a waste of CPU cycles. Don't inflate your code for no reason.

  • #5 Robert Nyman - author
    May 30th, 2009 at 1:14

    Henrik,

    Well, yes and no. I agree that JavaScript should be kept small, but it's also about making it easy for new adopters to understand and use javaScript in the best possible way.

    Richard,

    Don't really have any performance tests on this, but it's also about being able to write JavaScript code as you would do in other languages. So, there are more factors that play into role here.

  • #6 links for 2009-05-31 | burningCat
    May 31st, 2009 at 14:05

    [...] Getters and setters with JavaScript – code samples and demos (tags: javascript tutorial) [...]

  • #7 Allen Wirfs-Brock
    June 18th, 2009 at 21:24

    Robert,
    IE8 getter/setter support is directly based upon what is being standardized in ECMAScript 5. The ECMAScript committee (which includes participants from all the major browser vendors) explictly decided to use this new getter/setter design over the __defineGetter__/__defineSetter__ alternative. See the rationale document for an explanation of the thinking behind the new design.
    Another reason for choosing a new API for a feature like this is that while several browser support the __defineX__ API there are actually subtle semantic variations among the various implementations. One of the jobs of a standard is to iron out these differences, but the end result of this is that at least some, if not all existing implementation need to change to conform to the standard. By using a new API, the legacy non-standard APIs can be preserved by existing implementation providing full compatability for existing code that depends upon them.

    Allen Wirfs-Brock
    Microsoft

  • #8 Robert Nyman - author
    June 19th, 2009 at 0:00

    Allen,

    Absolutely, and it's good to have that standardization. What I mean, though, is that perhaps Internet Explorer could have offered both, to get the result of the same (or almost, as you point out) looking code for all web browser, and there could be a future code branching for the standardized approach.

    Personally, I think as it is now, very few people will use getters and setters, just because they deem it a hassle.

  • #9 Allen Wirfs-Brock
    June 19th, 2009 at 20:02

    One consideration was that once a feature (for example, __defineX__) exists in all major browsers it is almost impossible to get rid of it, even if there is a better standardize alternative.

    Eventually all browsers will support Object.defineProperty and the hassle will go away. In the meantime, it is trivial to define __defineX__ methods in terms of Object.defineProperty or to define an equivalant functionality subset of Object.defineProperty using __defineX__ methods. This makes it pretty easy for applicaiton developers to choose to use whichever API they prefer in the body of their code.

    Allen Wirfs-Brock

    Microsoft

  • #10 Robert Nyman - author
    June 19th, 2009 at 21:06

    Allen,

    Yes. However, in my experience,developers in general don't want to choose, they just want a de-facto way of doing it.

  • #11 Mark Willis
    August 26th, 2009 at 22:06

    What's the point! How can I use getters/setters when Microsoft uses a different mechanism than the rest of the world. My opinion from reading the rational document is that JavaScript was so poorly designed they are now having difficulties implementing something that should be simple.

  • #12 Robert Nyman - author
    August 26th, 2009 at 22:10

    Mark,

    Well, for library developers and others, it might be a good way to control code. But I agree, for the everyday-developer, it's not that interesting until it works the same way across web browsers.

  • #13 Thank you for 2009 – Happy New Year! – Robert’s talk
    December 30th, 2009 at 0:34

    [...] 28: Getters and setters with JavaScript – code samples and demos [...]

  • #14 Javascript getters and setters « somethingkindawierd
    October 5th, 2010 at 6:13

    [...] two most help­ful dis­cus­sions on javascript get­ters and set­ters come from John Resig and Robert Nyman. You’ll quickly learn when using get­ters and set­ters they are not defined the same in every [...]

  • #15 stephband
    November 11th, 2010 at 15:18

    Just thought I’d point out that IE9 now supports the ‘De-facto’ method of declaring getters and setters.

    var obj = {
    get thing(){},
    set thing(){}
    };

    Yahay!

  • #16 Robert Nyman - author
    November 15th, 2010 at 12:58

    stephband,

    Interesting!

  • #17 Quora
    September 29th, 2011 at 14:54

    How are object getters and setters used in JavaScript?…

    Robert Nyman explains them better here, http://robertnyman.com/2009/05/28/getters-and-setters-with-javascript-code-samples-and-demos/…

  • #18 Quora
    October 10th, 2011 at 2:57

    How are object getters and setters used in JavaScript?…

    UPDATE: In my post, below, I claim that get and set are not legal operators in Javascript. Actually, it depends on which version you’re using. They are legal in ECMAScropt 5 (as Rick Waldron and Andy Farrell pointed out). This is the most recent versi…

  • #19 trojani
    January 29th, 2012 at 23:29

    var lost = {loc : “Island”} //done: lost.loc >> Island
    lost.loc = “my Island” //Done!

    document.body.description = “Beautiful body”; //done!

    What getter [?!] -what setter [!! ?]

    This is Java Script sunny, and its a live and pure.
    p.s: wtf ‘setter’?!

  • #20 Robert Nyman - author
    January 30th, 2012 at 10:31

    trojani,

    It’s not about just setting values, it’s about controlling how they are applied/changed and to be more in line with other programming languages.

Write a comment

Share your thoughts:

HTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> . If you want to display code examples, please remember to write &lt; for < and &gt; for >.