Javascript automatic getter/setters (John Resig Book) Javascript automatic getter/setters (John Resig Book) javascript javascript

Javascript automatic getter/setters (John Resig Book)


I think it's best not to use the new keyword at all when working in JavaScript.

This is because if you then instantiate the object without using the new keyword (ex: var user = User()) by mistake, *very bad things will happen...*reason being that in the function (if instantiated without the new keyword), the this will refer to the global object, ie the window...

So therefore, I suggest a better way on how to use class-like objects.

Consider the following example :

var user = function (props) {    var pObject = {};    for (p in props) {        (function (pc) {            pObject['set' + pc] = function (v) {                props[pc] = v;                return pObject;            }            pObject['get' + pc] = function () {                return props[pc];            }        })(p);    }    return pObject;}

In the above example, I am creating a new object inside of the function, and then attaching getters and setters to this newly created object.

Finally, I am returning this newly created object. Note that the the this keyword is not used anywhere

Then, to 'instantiate' a user, I would do the following:

var john = user({name : 'Andreas', age : 21});john.getname(); //returns 'Andreas'john.setage(19).getage(); //returns 19

The best way to avoid falling into pitfalls is by not creating them in the first place...In the above example, I am avoiding the new keyword pitfall (as i said, not using the new keyword when it's supposed to be used will cause bad things to happen) by not using new at all.


EDIT: now, adapting Jason's answer, it works:

We need to make a closure for the values. Here's one way:

function bindAccessors(o, property, value) {  var _value = value;  o["get" + property] = function() {    return _value;  };  o["set" + property] = function(v) {    _value = v;  };}

Then the User constructor looks like this:

function User( properties ) {  for (var i in properties ) {    bindAccessors(this, i, properties[i]);  }}


you probably want something like this, which is more readable: (closures are easy to learn once you get some practice)

function User( properties ) {  // helper function to create closures based on passed-in arguments:  var bindGetterSetter = function(obj,p,properties)  {    obj["get"+p]=function() { return properties[p]; }    obj["set"+p]=function(val) { properties[p]=val; return this; }  };  for (var p in properties)    bindGetterSetter(this, p, properties);}

I also added "return this;" so you can do:

u=new User({a: 1, b:77, c:48});u.seta(3).setb(20).setc(400)