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...