Mohammed Imran Khan
Mohammed Imran Khan

Reputation: 179

Difference between style of defining setter and getter in Javascript

I was exploring setter and getter in JavaScript:

CODE1:

http://jsfiddle.net/imrukhan/7j8ZS/3/

ref : http://whereswalden.com/2010/04/16/more-spidermonkey-changes-ancient-esoteric-very-rarely-used-syntax-for-creating-getters-and-setters-is-being-removed/

<html>
    <head>
        <script>
            var Person = function(name){
                this.name = name;
                defineGetter(this, "Name", function() {
                    console.log("inside getter method");
                    return this.name;
                }); 
                defineSetter(this, "Name", function(val) {
                    console.log("inside setter method");
                    this.name = val;
                }); 
            }
            function accessorDescriptor(field, fun) {
              var desc = { enumerable: true, configurable: true };
              desc[field] = fun;
              return desc;
            }

            function defineGetter(obj, prop, get) {

                if (Object.defineProperty)
                    return Object.defineProperty(obj, prop, accessorDescriptor("get", get));
                if (Object.prototype.__defineGetter__)
                    return obj.__defineGetter__(prop, get);

                throw new Error("browser does not support getters");
            }

            function defineSetter(obj, prop, set) {

                if (Object.defineProperty)
                    return Object.defineProperty(obj, prop, accessorDescriptor("set", set));
                if (Object.prototype.__defineSetter__)
                    return obj.__defineSetter__(prop, set);

                throw new Error("browser does not support setters");
            }

            function fun(){
                var per = new Person("ABC");
                console.log(per.Name);
                per.Name = "XYZ";
                console.log(per.Name);
            }

        </script>
    </head>
    <body>
        <input type="button" value="click" onclick="fun()"/>
    </body>
</html>

CODE2:

http://jsfiddle.net/imrukhan/9H2U6/1/

ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Using_object_initializers

<!DOCTYPE HTML>

<html>
    <head>
        <script>
            var Person = function(name) {
                this._name = name;
            };

            Object.defineProperty(Person.prototype, "name", {
                get: function() {
                    console.log("inside getter method");
                    return this._name;
                },
                set: function(val){
                    console.log("inside setter method");
                    this._name = val;
                }
            });

            function fun(){
                var per = new Person("ABC");
                console.log(per.name);
                per.name = "XYZ";
                console.log(per.name);
            }

        </script>
    </head>
    <body>
        <input type="button" value="click" onclick="fun()"/>
    </body>
</html>

My Queries:
1) Is there any functional difference between CODE1 & CODE2 except style ?
2) What is the best way to define a Setter and Getter in JavaScipt (CODE1 /CODE2 /Please suggest any other)?

Thanks for the help.

Upvotes: 4

Views: 475

Answers (2)

Xotic750
Xotic750

Reputation: 23482

CODE1 uses the ECMA5 standard if available otherwise falls back to the non-standard.

CODE2 uses the ECMA5 standard only.

Best depends on the environment you are coding for, wider browser support or just ECMA5.

I believe the following three links should give you all the information that you require.

defineGetter

defineProperty

Defining getters and setters

Sure there are many ways of writing your example codes in other manners, 2 examples.

Variation of CODE1, (feature detect once, assign to prototype)

var defineGetter,
    defineSetter;

function accessorDescriptor(field, fun) {
    var desc = {
        enumerable: true,
        configurable: true
    };

    desc[field] = fun;
    return desc;
}

if (Object.defineProperty) {
    defineGetter = function defineGetter(obj, prop, get) {
        return Object.defineProperty(obj, prop, accessorDescriptor("get", get));
    };

    defineSetter = function (obj, prop, set) {
        return Object.defineProperty(obj, prop, accessorDescriptor("set", set));
    };
} else {
    if (Object.prototype.__defineGetter__) {
        defineGetter = function (obj, prop, get) {
            return obj.__defineGetter__(prop, get);
        };
    } else {
        throw new Error("browser does not support getters");
    }

    if (Object.prototype.__defineSetter__) {
        defineSetter = function (obj, prop, set) {
            return obj.__defineSetter__(prop, set);
        };
    } else {
        throw new Error("browser does not support setters");
    }
}

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

defineGetter(Person.prototype, "Name", function () {
    console.log("inside getter method");
    return this.name;
});

defineSetter(Person.prototype, "Name", function (val) {
    console.log("inside setter method");
    this.name = val;
});

Variation of CODE2 (without defineProperty)

var Person = function (name) {
    this.name = name;
};

Person.prototype.name = {
    get: function () {
        console.log("inside getter method");
        return this.name;
    },

    set: function (val) {
        console.log("inside setter method");
        this.name = val;
    }
};

Upvotes: 0

Radek Pech
Radek Pech

Reputation: 3098

One thing you should consider in the code is:

In CODE1 each instance of the Person will have own methods for getter and setter. It means if you create 10 persons, you will have 20 methods for getters and setters.

While in CODE2 it will create only one getter and one setter methods that will be shared by all instances of Person.

So if you're going for Web/App that can create lots of instances, you should definitely go with the CODE2.

Upvotes: 1

Related Questions