1

According to the Google style guide, methods should be defined on the prototype of a constructor and properties should be defined in the constructor using the this keyword.

I do most of my front end development using Knockout, which handles observing properties by turning them into functions. That is, all of my properties are now methods, more or less. Is this a significant performance hit? Are there any Knockout workarounds using JavaScript getters and setters?

Matthew James Davis
  • 12,134
  • 7
  • 61
  • 90

1 Answers1

1

So first, yes there is a plugin for knockout that uses getters and setters, but it only works in newer browsers. You sacrifice compatability to IE8< (this is unavoidable, since those browsers do not support javascript getters/setters). The plugin can be found here.

To your main point: understanding the style guides intent is important. Because methods are usually reusable, putting them on the prototype saves duplicated code and memory allocation. This is why it is a recommendation to put them on the prototype. However, knockout observables are not reusable. They behave like properties: they store information specific to an instance. This difference is important. They may be functions, but they are treated like properties.

The Google style guide simply does not address this scenario. It is not a performance hit to place them on the instance, because you are comparing it to a scenario that will not work. Placing observable's on the prototype will break the model. It isn't a performance hit to do the only thing that works.

As a final note, the getters and setters plugin doesn't make the functions disappear, it just hides them behind the getter and setter. Performance will not improve, because the same work still has to be done.

Kyeotic
  • 19,697
  • 10
  • 71
  • 128
  • I don't know knockout but what exactly makes the functions instance dependent? If data is stored on the object then there is no need to create the functions separately for each object. – Esailija Aug 27 '13 at 12:05
  • The functions have to close around the instance data, and they have to intercept reading and writing so that subscribers can be notified of changes. The functions have a list of subscribers that they must publish to, which is instance depedendant (you don't have access to it), as well as notify readers like computed that an observable is being read so they readers know to establish a subscription.. – Kyeotic Aug 27 '13 at 15:25
  • Actually that is just knockout idiosyncrasy and not a real limitation. There is absolutely no reason it couldn't use something like this: http://jsfiddle.net/Y6Dds/ (yes, some people could consider strings awkward but Ember gets away with that just fine) – Esailija Aug 27 '13 at 15:38
  • @Esailija I don't know why you brought strings up, but that code you posted is going to cause any objects that have those on the prototype to *share the data between them*. Certainly you don't want every viewmodel to share its `firstName` with every other viewmodel of the same type? – Kyeotic Aug 27 '13 at 16:07
  • `.firstName()` is the method, something like `__firstName$` (or whatever mangling you prefer) is the actual data stored on the instance, accessible through `this` based on the string `"firstName"`. A function that only uses `this` and locals can be shared whereas closures cannot. – Esailija Aug 27 '13 at 16:15
  • @Esailija Sorry, but you are very wrong about this. Take a look at [this fiddle](http://jsfiddle.net/Y6Dds/1/). Notice the shared property (it logs to the console). Knockout obserables behave like properties, because they store instance data internally using a closure. If you put observables on the prototype, all instances will share their values. I notice that you have high rep in javascript, but none in knockout. I can see why this is confusing if you haven't used knockout before, but *it does not behave like normal JS in this way*. – Kyeotic Aug 27 '13 at 16:58
  • You misunderstood, I said there is no reason knockout to have this limitation because if state can be stored in a closure, it can be stored on the object too. You showed me jsfiddle with actual knockout which of course doesn't implement it. My jsfiddle simply showed a skeleton API that would make it possible to share functions. – Esailija Aug 27 '13 at 17:44
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/36355/discussion-between-tyrsius-and-esailija) – Kyeotic Aug 27 '13 at 18:07