17

I'd like to create a class in JS that uses native getters and setters. I know I can create getters/setters for objects, like so:

var obj = {
    get value(){
        return this._value;
    },
    set value(val){
        this._value = val;
    }
}

I also know that I can use this.__defineGetter__ inside a class/function, but MDN says that using __defineGetter__() etc is discauraged.

Is there any better way to add getters and setters to js class than:

function class(){
};

class.prototype = {
   get value(){
        //....

}

?

2

3 Answers 3

22

2019: Hooray for ES6!

class Person {
    
    get name() {
        return this._name + '!!!'
    }

    set name(newValue) {
        this._name = newValue
    }

    constructor(name) {
        this._name = name
    }
}

const me = new Person('Zach')
console.log(me.name)            // Zach!!!

me.name = 'Jacob'
console.log(me.name)            // Jacob!!!

// Of course, _name is not actually private.
console.log(me._name)           // Jacob

Sign up to request clarification or add additional context in comments.

2 Comments

In case you're looking for truly private fields, take a look here. Private class field is still in TC39 stage 3 as of 2020-04-30, but has nonetheless already gained support on quite a few platforms, notably NodeJS since v 12.0.
Private classes have been supported since early 2021 in most browsers. Just use #name instead of _name. See here: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
11

The cleanest way to define properties on a class is via Object.defineProperties. This allows you to define all of your properties in a single, easily readable block. Here's an example:

var MyClass = function() {
    this._a = undefined;
    this._b = undefined;
};

Object.defineProperties(MyClass.prototype, {
    //Create a read-only property
    a : {
        get : function() {
            return this._a;
        }
    },
    //Create a simple read-write property
    b : {
        get : function() {
            return this._b;
        },
        set : function(value) {
            this._b = value;
        }
    }
});

There are a plethora of other options when defining properties, so be sure to check out the link I posted for more information. It's also important to keep in mind that even the most basic getter/setter property is only as fast as a method call in current browsers, so they can become a bottleneck in performance-intensive situation.

Comments

-2

How about this implementation:

function makeObject(obj, name) {
    // The property
    var value;

    // The setter
    obj["get" + name] = function() {return value;};

    // The getter
    obj["set" + name] = function(v) {
        value = v;
    };
}

To experiment:

var obj = {};
makeObject(obj, "Name");
obj.setName("Lolo");
print(obj.getName());

Of course, you can test name for validity before storing it in value. The test can be supplied as an additional argument to the makeObject function.

3 Comments

Yes, that is one way to define getters and setters, but what's great about 'get' and 'set' syntax is that the functions get triggered on regular assignment, that is on 'obj.value=2' the setter function is being called
These are not "native getters and setter" as were asked for.
@user2845946 Looks like you replied to me and then deleted the comment? You said you just down voted me "at random". Retaliatory serial down voting action like that is not just mean, that's a disservice to the community as a whole. If you can put a disclaimer in your answer that it is not an alternative way to create native getters and setters, then I'll undo my down vote. Otherwise, I think the answer is misleading, as people may think it's an alternative synax for creating native getters and setter, but it's not. If you're presenting a workaround, then please state it as such.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.