1

I thought I understood the purpose of get and set functions in accessors. But in a tutorial (W3Schools) they give this example. Notice that the first three are get and the last two are set. Why aren't they all set if we are trying to mutate counter?

// Define an object
var obj = {counter:0};

// Define Setters and Getters
Object.defineProperty(obj, "reset", {
  get : function () {this.counter = 0;}
});
Object.defineProperty(obj, "increment", {
  get : function () {this.counter++;}
});
Object.defineProperty(obj, "decrement", {
  get : function () {this.counter--;}
});
Object.defineProperty(obj, "add", {
  set : function (value) {this.counter += value;}
});
Object.defineProperty(obj, "subtract", {
  set : function (value) {this.counter -= value;}
});
Bret Hess
  • 407
  • 4
  • 10

4 Answers4

2

It's not really about mutating / not mutating here but rather about needing to pass an argument (set - on the right hand side of the = operator) or not (get). If you look at the example given by W3Schools:

// Play with the counter:
obj.reset;
obj.add = 5;
obj.subtract = 1;
obj.increment;
obj.decrement;

you'll notice that add and subtract (the "setters") have arguments (5 and 1) whereas reset / increment / decrement don't have any arguments ("getters").

Jb31
  • 1,381
  • 1
  • 10
  • 19
2

set requires a value on the right side of the = operator.

obj.add = 5

get requires no = at all, and therefore no other value.

obj.increment

That said, this is a very contrived example. If your getters and setters name's are verbs, you probably just want them to be functions.

Alex Wayne
  • 178,991
  • 47
  • 309
  • 337
  • I read that get and set are keywords, and assumed thay had different purposes (hence restrictions). Why have the concept of "get" if "get" can be used to "set"? – Bret Hess Jan 13 '20 at 19:19
  • 1
    "get" can only be used to set "static" values (e.g. 0, +1, -1 in your examples above). "set" can be used to set "dynamic" values (e.g +x, -y) – Jb31 Jan 13 '20 at 19:33
  • 1
    @BretHess when your getter or setter is a function (as it is in your example) you can make that function do a great many things. There is no technical restriction that forces a getter function to be read only. It simply runs some code that eventually returns a value. There is also no technical restriction on forcing a setter to actually set a value. All this does is setup some special syntax that calls custom function. `obj.property` calls a custom getter function that can do anything, and `obj.property = newValue` calls a custom setter function that can do anything. – Alex Wayne Jan 13 '20 at 19:40
  • 1
    @AlexWayne This is exactly right, which is why I don't see a whole lot of (if any?) people using getters/setters. They seem to have been added to appease the Classical dev community without really adding much to the feature-set of the language. They're ambiguous and the implementation is unopinionated, which leads to the exact confusion the OP had. Anyway, that's just my $0.02. – mhodges Jan 13 '20 at 20:21
2

The reason set is used in the add and subtract methods is because they take an argument to the function, whereas increment and decrement do not. By definition, getters do not take arguments, while setters do. Technically they could have used set with increment and decrement, but it really doesn't make a whole lot of difference, and to be quite honest, I don't see a whole lot of people using getters/setters to begin with.

Here's a stack overflow post explaining more about the difference between set/get with arguments

mhodges
  • 10,938
  • 2
  • 28
  • 46
0

Syntax

Object.defineProperty(obj, prop, descriptor)

obj:The object on which to define the property.

prop:The name or Symbol of the property to be defined or modified.

descriptor:The descriptor for the property being defined or modified.

set : In set we pass an argument.

get : In get we use an argument/Pre-defined arguement.

// Define an object
var obj = {counter:0};

// Define Setters and Getters
Object.defineProperty(obj, "reset", {
  get : function () {this.counter = 0;}
});
Object.defineProperty(obj, "increment", {
  get : function () {this.counter++;}
});
Object.defineProperty(obj, "decrement", {
  get : function () {this.counter--;}
});
Object.defineProperty(obj, "add", {
  set : function (value) {this.counter += value;}
});
Object.defineProperty(obj, "subtract", {
  set : function (value) {this.counter -= value;}
});

I hope you understand why we are used like this here. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty