# class-set-return

**URL:** <https://es.discourse.group/t/class-set-return/461>\
**Category:** 🦋 Proposals\
**Tags:** proposal\
**Created:** [September 9, 2020, 3:57pm UTC](https://es.discourse.group/t/class-set-return/461 "2020-09-09T15:57:42Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![accidentlywoo](https://avatars.discourse-cdn.com/v4/letter/a/919ad9/32.png) [@accidentlywoo](https://es.discourse.group/u/accidentlywoo)\
**Post date:** [September 9, 2020, 3:57pm UTC](https://es.discourse.group/t/class-set-return/461/1 "2020-09-09T15:57:42Z")

</div>

class setter's behavior is ambiguous  
The value assigned to setter is returned as it is,  
Let me take a very inconvenient example. (the sample from [refactoring 2th - 7.3])

```javascript
class Order{
    constructor(data = {priority: "normal"}){
        this._priority = new Priority(data.priority);
    }
    set priority(aString){this._priority = new Priority(aString);} 
}
class Priority{
    constructor(value){
        if(value instanceof Priority) return value;
        if(Priority.legalValues().includes(value)) this._value = value;
        else console.error(`<${value}> is invalid for Priority`);
    }
    toString() {return this._value;}
    get _index() {return Priority.legalValues().findIndex(s => s === this._value);}
    static legalValues() {return ['low', 'normal', 'high', 'rush'];}

    equals(other) {return this._index === other._index;}
    higherThan(other) {return this._index > other._index;}
    lowerThan(other) {return this._index < other._index;}
}

```

The problem arises with the Client

```javascript
(new Order().priority = 'normal').priority.higherThan(new Priority("low"));

```

this code's result is 'undefined' because `new Order().priority = 'normal'` return 'nomal'

But.

```javascript
let orderSet = new Order();
orderSet.priority = "high";

orderSet.priority.higherThan(new Priority("low"));

```

it's work.

Do you guys agree how uncomfortable and unnatural this is?

AND,

I put the return code in Order Class

```javascript
class Order{
    constructor(data = {priority: "normal"}){
        this._priority = new Priority(data.priority);
    }
    set priority(aString){this._priority = new Priority(aString); return this;} 
}

```

highlight again

```javascript
set priority(aString){this._priority = new Priority(aString); return this;} 

```

In this statement, return is ignored.

**I think this behavior is the same as inducing the writing of bad code like the one below.**

```javascript
class Order{
    constructor(data = {priority: "normal"}){
        this._priority = new Priority(data.priority);
    }
     setPriority(aString){this._priority = new Priority(aString); return this;}
}

```

Client

```javascript
(new Order().setPriority('normal')).priority.higherThan(new Priority("low"));

```

This works the way i want

You must make it possible to remove or overwrite the return statement of the set. I think it's better to have no return statement

#### Proposal: [https://github.com/tc39/proposal-class-set-return](https://github.com/tc39/proposal-class-set-return)

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [September 9, 2020, 4:13pm UTC](https://es.discourse.group/t/class-set-return/461/2 "2020-09-09T16:13:55Z")

</div>

Why is your desired chaining code cleaner to read and understand than the multiple-statement code?

Why is the `.setPriority` code worse than the setter code, when it already works how you want?

---

<div class="post-metadata">

**Author:** ![accidentlywoo](https://avatars.discourse-cdn.com/v4/letter/a/919ad9/32.png) [@accidentlywoo](https://es.discourse.group/u/accidentlywoo)\
**Post date:** [September 9, 2020, 5:09pm UTC](https://es.discourse.group/t/class-set-return/461/3 "2020-09-09T17:09:06Z")

</div>

'set'  
I think the property approach is a good expression.  
But what is the reason for using a 'set'  
I don't know if there is any meaning as a special method used by attaching 'set'  
In this way, you can just use the property access method.

I hope there will be no more 'this and that' stacks of js

---

<div class="post-metadata">

**Author:** ![bergus](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/bergus/32/152_2.png) [@bergus](https://es.discourse.group/u/bergus)\
**Post date:** [September 9, 2020, 8:29pm UTC](https://es.discourse.group/t/class-set-return/461/4 "2020-09-09T20:29:03Z")

</div>

Hello!

> [@accidentlywoo](#):
>
> Do you guys agree how uncomfortable and unnatural this is?

No, I don't agree. I think the unnatural part here is chaining off an assignment in a grouping parenthesis (`(x = y).…`). The fluent syntax with the method is much better (although I don't understand what the `Order` in the example is good for at all, one could just write `new Priority('normal').higherThan(new Priority('low'))`?).

What I think is much more important though is to not break the invariant that in `x = y = z` the result value of `z` is assigned to both `x` and `y`, no matter what `x` and `y` are or whether their setters return anything.

---

<div class="post-metadata">

**Author:** ![accidentlywoo](https://avatars.discourse-cdn.com/v4/letter/a/919ad9/32.png) [@accidentlywoo](https://es.discourse.group/u/accidentlywoo)\
**Post date:** [September 10, 2020, 5:11am UTC](https://es.discourse.group/t/class-set-return/461/5 "2020-09-10T05:11:39Z")

</div>

Thank U!  
I fully agree

'set'  
I expanded my opinion a little more,  
Since setter is a property approach, it sounds like a better idea to behave like a function caller.

```javascript
new Order().priority('normal')).priority.higherThan(new Priority("low")

```

---

<div class="post-metadata">

**Author:** ![accidentlywoo](https://avatars.discourse-cdn.com/v4/letter/a/919ad9/32.png) [@accidentlywoo](https://es.discourse.group/u/accidentlywoo)\
**Post date:** [September 10, 2020, 5:24am UTC](https://es.discourse.group/t/class-set-return/461/6 "2020-09-10T05:24:12Z")

</div>

The core of my suggestion is why JS setters are assigned like properties, actions are like methods, and return is like properties?

I am very curious about the reason for this design.  
At the time of introduction of class,  
I am sorry for the convenience of simple usability or the use of some expressions like JS.

---

<div class="post-metadata">

**Author:** ![blob](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/blob/32/2230_2.png) [@blob](https://es.discourse.group/u/blob)\
**Post date:** [April 4, 2023, 10:59am UTC](https://es.discourse.group/t/class-set-return/461/7 "2023-04-04T10:59:32Z")

</div>

I had a hard time understanding what this proposal is suggesting.  
Firstly, setters are not unique to classes.  
Secondly, the snippet of code you claim returns `undefined` actually throws an error.  
Thirdly, I was constantly distracted by the sheer inefficiency of having a function `legalValues` that constructs two new arrays every time you would like to compare a priority to another.

For a bit more constructive criticism, I actually like the idea of setters being able to return a value, but I unfortunately see no applicable value to this. I don't use setters to transform values, as this produces unintuitive code (i.e I'm assigning a string to this field, so I expect that field to be a string, but it's actually a trap that returns a `Priority` object). The primary use for getters/setters is for computed / externally-stored values (e.g your `get _index` is a computed value)
