tags:

views:

1230

answers:

8

I've been trying to get my head around getters and setters and its not sinking in. I've read JavaScript Getters and Setters and Defining Getters and Setters and just not getting it.

Can someone clearly state:

  1. What a getter and setter are meant to do, and
  2. Give some VERY simple examples?
+1  A: 

I think the first article you link to states it pretty clearly:

The obvious advantage to writing JavaScript in this manner is that you can use it obscure values that you don't want the user to directly access.

The goal here is to encapsulate and abstract away the fields by only allowing access to them thru a get() or set() method. This way, you can store the field/data internally in whichever way you want, but outside components are only away of your published interface. This allows you to make internal changes without changing external interfaces, to do some validation or error-checking within the set() method, etc.

matt b
+1  A: 

You'd use them for instance to implement computed properties.

For instance:

function Circle(radius) {
    this.radius = radius;
}

Circle.prototype = {
    get circumference() {
        return 2*Math.PI*this.radius;
    }

    get area() {
        return Math.PI*this.radius*this.radius;
    }
}

c = new Circle(2);
console.log(c.area); // Should output 12.566
Sii
Ok, I think I'm starting to get it.I'm trying to assign a getter to the length property of an array object but getting an error: "Redeclaration of var length"And the code looks like this: obj = []; obj.__defineGetter__('length',function(){ return this.length; });
That's because Array objects already have a builtin length property. If the redeclaration was allowed, calling the new length would recurse infinitely. Try calling the property "my_length" or some such.
Sii
+1  A: 

Getters and Setters are just general concepts that do exactly what the name says: Get a variable/object, and Set a variable/object.

Here's how I personally "get" and "set" my own variables:

var data = "Hello World"

Some people sometimes need to abstract things out, so they do that instead:

function get(value){
    [...]
}

function set(name,value){
    [...]
}

set("data","Hello World");
var data = get("data");

I don't use Getters and Setters much, but there are some good uses for them, for example when you need to abstract out the way a variable is stored/accessed.

Wadih M.
+1  A: 

Have a look at:

Defining Getters and Setters

and this

Javascript Bible

DaDa
+1  A: 

If you're referring to the concept of accessors, then the simple goal is to hide the underlying storage from arbitrary manipulation. The most extreme mechanism for this is

function Foo(someValue) {
    this.getValue = function() { return someValue; }
    return this;
}

var myFoo = new Foo(5);
/* We can read someValue through getValue(), but there is no mechanism
 * to modify it -- hurrah, we have achieved encapsulation!
 */
myFoo.getValue();

If you're referring to the actual JS getter/setter feature, eg. defineGetter/defineSetter, or { get Foo() { /* code */ } }, then it's worth noting that in most modern engines subsequent usage of those properties will be much much slower than it would otherwise be. eg. compare performance of

var a = { getValue: function(){ return 5; }; }
for (var i = 0; i < 100000; i++)
    a.getValue();

vs.

var a = { get value(){ return 5; }; }
for (var i = 0; i < 100000; i++)
    a.value;
olliej
+3  A: 

Getters and setters really only make sense when you have private properties of classes. Since Javascript doesn't really have private class properties as you would normally think of from Object Oriented Languages, it can be hard to understand. Here is one example of a private counter object. The nice thing about this object is that the internal variable "count" cannot be accessed from outside the object.

var counter = function() {
    var count = 0;

    this.inc = function() {
        count++;
    };

    this.getCount = function() {
        return count;
    };
};

var i = new Counter();
i.inc();
i.inc();
// writes "2" to the document
document.write( i.getCount());

If you are still confused, take a look at Crockford's article on Private Members in Javascript.

John
A: 

In addition to @Sii's answer, setters can also be used to update other values.

function Name(first, last) {
    this.first = first;
    this.last = last;
}

Name.prototype = {
    get fullName() {
        return this.first + " " + this.last;
    },

    set fullName(name) {
        var names = name.split(" ");
        this.first = names[0];
        this.last = names[1];
    }
};

Now, you can set fullName, and first and last will be updated and vice versa.

Matthew Crumley
A: 

I've got one for you guys that might be a little ugly, but it does get'er done across platforms

function myFunc () {

var _myAttribute = "default";

this.myAttribute = function() {
    if (arguments.length > 0) _myAttribute = arguments[0];
    return _myAttribute;
}
}

this way, when you call

var test = new myFunc();
test.myAttribute(); //-> "default"
test.myAttribute("ok"); //-> "ok"
test.myAttribute(); //-> "ok"

If you really want to spice things up.. you can insert a typeof check:

if (arguments.length > 0 && typeof arguments[0] == "boolean") _myAttribute = arguments[0];
if (arguments.length > 0 && typeof arguments[0] == "number") _myAttribute = arguments[0];
if (arguments.length > 0 && typeof arguments[0] == "string") _myAttribute = arguments[0];

or go even crazier with the advanced typeof check: type.of() code at codingforums.com