john resig - javascript getters and setters

Upload: rithuik1598

Post on 14-Apr-2018

219 views

Category:

Documents


0 download

TRANSCRIPT

  • 7/27/2019 John Resig - JavaScript Getters and Setters

    1/5

    10/1/13 John Resig - JavaScript Getters and Setters

    ejohn.org/blog/javascript-getters-and-setters/

    Home

    Blog

    About Me

    John ResigContact, Subscribe

    JavaScript Getters and Setters

    It is with much happiness that I think I can finally say, without seeming like a fool, that: JavaScript Getters and

    Setters are now prevalent enough to become of actual interest to JavaScript developers. Wow, Ive been

    waiting a long time to be able to say that.

    I want to start by giving a whirlwind tour of Getters and Setters and why theyre useful. Followed by a look into

    what platforms now support Getters and Setters as to make them relevant.

    Getters and Setters

    Getters and Setters allow you to build useful shortcuts for accessing and mutating data within an object.

    Generally, this can be seen as an alternative to having two functions with an object that are used to get and set a

    value, like so:

    1. {

    2. getValue: function(){

    3. return this._value;

    4. },

    5. setValue: function(val){

    6. this._value = val;

    7. }

    8. }

    The obvious advantage to writing JavaScript in this manner is that you can use it obscure values that you dont

    want the userto directly access. A final result looking something like the following (using a closure to store thevalue of a newly constructed Field):

    1. function Field(val){

    2. var value = val;

    3.

    4. this.getValue = function(){

    5. return value;

    6. };

    7.

    8. this.setValue = function(val){

    9. value = val;

    http://ejohn.org/about/http://eepurl.com/ywvS9http://ejohn.org/about/http://ejohn.org/about/http://ejohn.org/about/http://ejohn.org/about/http://ejohn.org/blog/http://ejohn.org/http://eepurl.com/ywvS9http://ejohn.org/about/http://ejohn.org/about/http://ejohn.org/about/http://ejohn.org/blog/http://ejohn.org/
  • 7/27/2019 John Resig - JavaScript Getters and Setters

    2/5

    10/1/13 John Resig - JavaScript Getters and Setters

    ejohn.org/blog/javascript-getters-and-setters/

    10. };

    11. }

    Some example results:

    1. var field = new Field("test");

    2. field.value

    3. // => undefined

    4. field.setValue("test2")

    5. field.getValue()6. // => "test2"

    Now, centered around this concept, is where getters and setters come into play. They allow you to bind special

    functions to an object that look like normal object properties, but actually execute hidden functions instead. The

    end result looks something like this:

    1. var field = new Field("test");

    2. field.value

    3. // => test

    4. field.value = "test2";

    5. field.value6. // => "test2"

    So lets look at how you would go about setting something like that up. Mimicking the hidden value property

    style of before, our code would look something like this:

    1. function Field(val){

    2. var value = val;

    3.

    4. this.__defineGetter__("value", function(){

    5. return value;

    6.});

    7.

    8. this.__defineSetter__("value", function(val){

    9. value = val;

    10. });

    11. }

    Now, if we wanted to, instead, define getters and setters within the context of our object prototype (and where

    having private data is less of a concern) we can then use an alternative object syntax for that.

    1. function Field(val){

    2. this.value = val;

    3. }4.

    5. Field.prototype = {

    6. get value(){

    7. return this._value;

    8. },

    9. set value(val){

    10. this._value = val;

    11. }

    12. };

    The syntax for getters and setters is typically what scare people the most about the feature. But after a little bit of

  • 7/27/2019 John Resig - JavaScript Getters and Setters

    3/5

    10/1/13 John Resig - JavaScript Getters and Setters

    ejohn.org/blog/javascript-getters-and-setters/

    use, its easy to get over.

    Heres another example, allowing a user to access an array of usernames (but denying them access to the

    original, underlying user objects.

    1. function Site(users){

    2. this.__defineGetter__("users", function(){

    3. // JS 1.6 Array map()

    4.return users.map(function(user){

    5. return user.name;

    6. });

    7. });

    8. }

    As a bonus, heres a method that Ive written that can help you to extend one object with another (a common

    JavaScript operation) while still taking into account getters and setters:

    1. // Helper method for extending one object with another

    2. function extend(a,b) {

    3. for ( var i in b ) {

    4. var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);5.

    6. if ( g || s ) {

    7. if ( g )

    8. a.__defineGetter__(i, g);

    9. if ( s )

    10. a.__defineSetter__(i, s);

    11. } else

    12. a[i] = b[i];

    13. }

    14. return a;

    15. }

    This code is from the Server-Side Browser Environment that I wrote about a week ago. Youll notice that, when

    looking through the code that I make liberal use of getters and setters to create this mock environment.

    Additionally, in my custom extend() method youll notice two new methods: __lookupGetter__ and

    __lookupSetter__. These are immensely useful, once you start dealing with getters and setters.

    For example, when I did my first pass at writing an extend() method, I started getting all sorts of errors I was

    thoroughly confused. Thats when I realized that two things were happening with the simple statement: a[i] =

    b[i];

    If a setter existed in object a, named i, and a getter existed in object b, named i, a[i]s value was being set not to

    the other setter function, but to the computed value from bs getter function. The two __lookup*__ methods

    allow you to access the original functions used for the methods (thus allowing you to write an effective extend

    method, for example).

    A couple things to remember:

    You can only have one getter or setter per name, on an object. (So you can have both one value getter

    and one value setter, but not two value getters.)

    http://dev.jquery.com/browser/trunk/jquery/build/runtest/env.jshttp://ejohn.org/blog/bringing-the-browser-to-the-server/
  • 7/27/2019 John Resig - JavaScript Getters and Setters

    4/5

    10/1/13 John Resig - JavaScript Getters and Setters

    ejohn.org/blog/javascript-getters-and-setters/

    The only way to delete a getter or setter is to do: delete object[name]; Be aware, that this command is

    capable of deleting normal properties, getters and setters. (So if all you want to do is remove a setter you

    need to backup the getter and restore it afterwards.)

    If you use __defineGetter__ or __defineSetter__ it will silently overwrite any previous named getter or

    setter or even property of the same name.

    Platforms

    Now, here is where things get really interesting. Up until just recently, talking about actually using getters and

    setters (outside of the context of Firefox/Gecko) was pretty much not happening.

    However, look at this line up:

    Browsers

    Firefox

    Safari 3+ (Brand New)

    Opera 9.5 (Coming Soon)

    I used the following snippet to test browsers:

    1. javascript:foo={get test(){ return "foo"; }};alert(foo.test);

    Additionally, the following JavaScript environments support Getters and Setters

    SpiderMonkey

    Rhino 1.6R6 (New)

    And as do the following ECMAScript implementations

    ActionScript

    JScript.NET 8.0

    Posted: July 18th, 2007

    Subscribe for email updates: email address Subscribe

    If you particularly enjoy my work, I appreciate donations given with Gittip.

    7 Comments (Show Comments)

    Comments are closed.

    Comments are automatically turned off two weeks after the original post. If you have a question concerning the

    content of this post, please feel free to contact me.

    http://ejohn.org/about/https://www.gittip.com/jeresighttp://developer.mozilla.org/en/docs/New_in_Rhino_1.6R6http://www.mozilla.org/js/spidermonkey/http://my.opera.com/desktopteam/blog/kestrel-is-coming
  • 7/27/2019 John Resig - JavaScript Getters and Setters

    5/5