Hacker News new | past | comments | ask | show | jobs | submit login

This is not a hard and fast rule and I have no idea if there is any pattern, but I reserve getters for trivial properties like `firstName + " " + lastName;`

If it does any non-trivial amount of work, then I always use a function. The reason for that is in codebases that I've worked on in the past, getters were heavily overused and people ended up writing code that while at a glance seemed entirely reasonable, it was actually doing an absurd amount of redundant work and was causing performance issues. I feel that requiring the `()` to invoke it as a function at least hints that "this does stuff" rather than hiding the implementation in a getter.

Does that make sense?




> I feel that requiring the `()` to invoke it as a function at least hints that "this does stuff" rather than hiding the implementation in a getter. Does that make sense?

It does. But don't you feel that making that distinction makes the code more inflexible for (arguably) little gain?

To put a concrete example, let's consider an "items left" property of a TODO list:

  class TodoList {
    // ...
    itemsLeft() {
      return _.count(this.todos, todo => !todo.done)
    }
  }
itemsLeft was defined as method because it's computed by iterating a list, so we deem it non-trivial. But let's say that later on we discover that a better internal structure for our TodoList is to have the unfinished and finished todo's in different lists, so our itemsLeft becomes "trivial":

  class TodoList {
    // ...
    itemsLeft() {
      return this.unfinishedTodos.length
    }
  } 
If using getters is preferable for trivial properties, should we then change itemsLeft to be a getter and refactor the existing code that uses it?

Besides, there's the problem of having to draw a line between trivial and non-trivial code (e.g., "is string concatenation trivial?", "but it's O(n+m) on the lengths of the strings!", etc). Using always the same style for accessors (either plain-old methods or getters), regardless of how complex the underneath code is, frees us from having to make this consideration in the first place and also leaves the door open for changing an object's implementation without changing its public interface.

---

I feel this perception probably depends on the language background tough. E.g., in languages like Ruby you always interact with objects via messages, so you never have this distinction of whether something is computed or not from a the caller's perspective (or at least not in a syntactic level).

But it's weird that this distinction is made in JS though, as many of the classic JS APIs have computed properties that "do stuff", and quite a lot! (e.g., Node#textContent). My guess is that most likely it's a result of the language lacking user-definable getters and setters for such a long time.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: