What is the argument for using ES6 getters and setters over getProperty/setProperty convention?

前端 未结 2 1857
天涯浪人
天涯浪人 2021-01-01 19:07
class Foo {
    getName = () => this.name;

    setName = (name) => this.name = name;
}

and

         


        
相关标签:
2条回答
  • 2021-01-01 19:44

    You cannot distinguish between a direct property access and method access.

    This is the main argument in their favour.

    One of the weirdest great pains of writing classic Java-style OO code is that any object with an exposed property on it has to have getters and setters written, and a huge amount of boilerplate comes rolling out of this, especially for large data-structure type objects (e.g. DTOs).

    The reasoning for all of these is that you can't just make properties public, because otherwise you can't ever add logic to them without breaking the API (e.g. logic to only allow settings certain values, or to refactor and store a property in a slightly different way while still exposing the same external API, or similar). See https://softwareengineering.stackexchange.com/questions/176876/why-shouldnt-i-be-using-public-variables-in-my-java-class for some typical arguments around this.

    I think you could comfortably say that this has been taken to its logical extreme in recent years, but that doesn't mean it's wrong; by exposing a public field for direct access you are indeed exposing the internal implementation of how you're storing that data, and that means you can't change it as easily or safely any more.

    ES6 getters/setters fix this. The fact that something is readable as a direct property on an object no longer tells you anything about the implementation of that property. It could have been a field originally, but recently turned into a ES6 property accessor instead, without the API changing. The implementation of the property is hidden from the rest of your codebase, and is therefore easier to change.

    The disadvantage is that it is not intuitive that a property that you are accessing might require heavy computational power (and therefore should be memoized) or that it changes every time you access it.

    You're right, this is a risk. That's also a gotcha with any getX() though; there's a strong convention suggesting that nice simple methods like 'getName()' shouldn't ever be doing expensive things behind the scenes, even if they are methods, and if you break that you'll almost certainly end up catching people out (including yourself, 6 months from now)

    Moving to properties doesn't change this, but you're right that ES6 means you're no longer guaranteed to be safe for simple property accesses. The answer is really just that you have to make sure you (and everybody else) sticks with convention and Principle of Least Astonishment: as with existing simple looking getters and setters, ES6 property accessors should do simple cheap things, and shouldn't have strange side effects elsewhere.

    0 讨论(0)
  • 2021-01-01 19:45

    There aren't any specific things you can't do with getMethod() and setMethod(), but it allows for different code styles. For instance you could, with a get foo and set foo, write:

    obj.foo++;
    

    which would call the getter then the setter. You could, of course, have the set function then validate that the value is within a specific range, for instance. The traditional code would look like:

    obj.setFoo(obj.getFoo() + 1);
    

    You cannot distinguish between a direct property access and method access.

    That's kinda the point. I'd argue that if something is really expensive, you just shouldn't use getters for it.

    0 讨论(0)
提交回复
热议问题