Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use getters/setters and when to safely omit them?

Tags:

ember.js

According to http://emberjs.com/guides/object-model/classes-and-instances/ it is required to access properties using getters and setters:

When accessing the properties of an object, use the get and set accessor methods.

Make sure to use these accessor methods; otherwise, computed properties won't recalculate, observers won't fire, and templates won't update.

I understand that it is needed to use setters when changing property to let Ember know about the change so it can update bindings, but what about reading properties?

Example from http://emberjs.com/guides/object-model/classes-and-instances/

App.Person = Ember.Object.extend({
  say: function(thing) {
    var name = this.get('name');
    alert(name + " says: " + thing);
  }
});

var yehuda = App.Person.create({
  name: "Yehuda Katz"
});

yehuda.say("Yes");

In the example above, this.get('name') is used to access property name, however method say is defined as a property of class App.Person and is accessed directly by dot notation. While there is a distinctive usage difference between method and property, in JavaScript, there's no difference in implementation of both. The example still works if I replace this.get('name') by this.name.

  1. Are there any implementation differences in Ember regarding methods and properties of object?
  2. Is it always safe to access methods directly?
  3. Must all properties including computed properties be always accessed by getter? If not, when is it safe to access properties directly?

I definitely want to stick to best practise here, which is to use getter/setter every time, but I'd like to understand the internals of Ember.js :)

like image 206
Ludeks Avatar asked May 15 '14 14:05

Ludeks


People also ask

Should I always use getters and setters?

If the question is between exposing the instance variable itself and using setters/getters, the answer is always to use setters/getters, because there are plenty of instances where a property can reasonably change from something stored in a variable to something calculated.

How do you avoid getters and setters?

The simplest way to avoid setters is to hand the values to the constructor method when you new up the object. This is also the usual pattern when you want to make an object immutable. That said, things are not always that clear in the real world. It is true that methods should be about behavior.

Where should getters and setters go?

The Java coding convention states that methods (getters and setters are methods) should be after constructors declarations. It just a convention and it exists to make code easier to read in general.

Should you use getters and setters within a class?

Yes, the methods of your class should call the getters and setters. The whole point in writing getters and setters is future proofing. You could make every property a field and directly expose the data to the users of the class.


1 Answers

  1. The definition of a method or a property in Ember is the same as in Vanilla JavaScript, but they are resolved different in Ember. You are not working with POJOs. Every time you extend from a Route/Controller/View, you are adding the Ember layer that processes methods and properties differently.
  2. No, is not always safe. In your case it is because it is overly simple.
  3. Yes, always access properties with get.

User interaction with your app is what causes changes in the properties of your objects, we handle those interactions with events. When an event in Ember is fired, it is not resolved immediately, instead it is put in a priority queue and resolved at a later time.

Properties are updated and read in an asynchronous form, if you access them directly using this there is no guarantee that you'll get the most up to date value.

Check: Managing Asynchrony

When you make a change to a property in Ember, it does not immediately propagate that change. Instead, it invalidates any dependent properties immediately, but queues the actual change to happen later.

So, when you change the value of a property, this is roughly what happens:

  1. A property is changed
  2. All dependent properties are invalidated
  3. Queues the actual change for later
  4. Wait for any other event handlers, for the current user, to finish
  5. Flush the changes queue
    • Until here, the property is actually updated (and this would work as usual)

Imagine you use this to read a property, but some other event occurs that changes its value. The new value won't be available until the queue is flushed, but this reads immediately the property and returns the value of a property that is scheduled to be updated soon. You get stale data. The methods get and set manage this asynchrony for you and guarantee fresh values always.

When you have only one property, in the whole app, this asynchronous mechanism won't be noticed.

There are many different queues in Ember, and the fundamental mechanism behind all this is the run loop.

like image 79
givanse Avatar answered Oct 21 '22 18:10

givanse