2

After struggling with my problem in this question, I found out that I can initialize an observable with an empty object like this:

abc = ko.observable({});

Old wisdom, back from Fortran etc, has it that you should always initialize your variables, so I am now inclined to initialize ALL ko.observables. This is NOT what I read in the tutorials on the knockout site. So my question is: should I only initialize where strictly needed, or is there no performance degradation if I do it everywhere?

Community
  • 1
  • 1
Roland
  • 4,619
  • 7
  • 49
  • 81

1 Answers1

4

I don't think you should worry about performance. You should worry about readable code, meaningful initial values and code without bugs.

Often, you'll see default values being used to make the developer's life easier. For example:

this.userInput = ko.observable("");
this.upperCaseUserInput = ko.computed(function() {
  return this.userInput().toUpperCase();
}, this);

Initializing with an empty string allows us to skip a null/undefined check in our computed. If we know we're going to bind to an input via a value binding, we can almost be sure that there's always going to be a toUpperCase method in our input's prototype. Initializing userInput with an empty object won't do us any good here: the lack of a function named toUpperCase will throw an error.

If you're dealing with complicated computeds and "nullable" observables, I think the best way to go is to include null checks in your computeds and introduce "layered"/safe computeds where possible. For example:

this.selectedPerson = ko.observable(); // Can be null, undefined or Person

// This computed is *always* a string
var fullName = ko.pureComputed(function() {
  var person = this.selectedPerson();

  return person 
    ? person.firstName + " " + person.lastName
    : "Unknown person";
}, this);

// So in this computed, we don't have to do any null checks
this.displayName = ko.pureComputed(function() {
  return "**" + fullName() + "**";
}, this);

If you want absolute type-safety, I'd suggest looking in to TypeScript. A TypeScript-knockout combination will allow you to define observables that can only contain a certain type of value, minimising the kinds of errors you were facing in the other question.

Note: I'm not sure if this answer is too opinion-based... If you feel it is, let me know. Question might be off-topic/too broad for stackoverflow...

user3297291
  • 22,592
  • 4
  • 29
  • 45
  • I think this is a fine answer. And the example of a person is a good one - if there's no one selected, it doesn't make sense to initialise it with an empty object - then you fall back to having to check if properties exist or not. Better to have "nothing" ie `null` representing nothing selected. In other cases, having a default value can be useful. It really depends on the use case, but I wouldn't say "yes, it's a good idea to initialise _all_ your observables". – James Thorpe Feb 22 '17 at 17:26
  • I found out that the initialization I proposed is not always helpful or sufficient. Thanks anyway for your answer, I will study it tomorrow. – Roland Feb 22 '17 at 17:48
  • Your answer surely helped me better understand what is possible with Knockout and what not, and ways to deal with null-values. – Roland Feb 23 '17 at 09:20