Utility Functions
Utility functions
Section titled “Utility functions”TKO provides helper functions for inspecting and converting observables.
Type checking
Section titled “Type checking”| Function | Returns true when |
|---|---|
ko.isObservable(value) | The value is an observable, observable array, or computed |
ko.isObservableArray(value) | The value is an observable array |
ko.isWritableObservable(value) | The value is a writable observable (not a read-only computed) |
ko.isComputed(value) | The value is a computed observable |
ko.isSubscribable(value) | The value is any subscribable (observable, computed, or raw subscribable) |
const name = ko.observable('TKO')const tags = ko.observableArray(['fast'])const upper = ko.computed(() => name().toUpperCase())
ko.isObservable(name) // trueko.isObservable(upper) // trueko.isObservable('plain') // falseko.isObservableArray(tags) // trueko.isObservableArray(name) // falseko.isWritableObservable(name) // trueko.isWritableObservable(upper) // falseko.isComputed(upper) // trueUnwrapping
Section titled “Unwrapping”ko.unwrap(value) reads the value if it’s an observable, or returns it as-is if it isn’t. Useful when a function accepts either an observable or a plain value:
ko.unwrap(ko.observable(42)) // 42ko.unwrap(42) // 42This is commonly used inside custom bindings where a parameter could be either type.
Serialization
Section titled “Serialization”ko.toJS and ko.toJSON convert an object graph containing observables into plain data.
ko.toJS(viewModel) — clones the object tree, replacing every observable with its current value:
const vm = { name: ko.observable('TKO'), tags: ko.observableArray(['fast', 'reactive']), nested: { count: ko.observable(3) }}
ko.toJS(vm)// { name: 'TKO', tags: ['fast', 'reactive'], nested: { count: 3 } }ko.toJSON(viewModel, replacer?, space?) — same as ko.toJS followed by JSON.stringify. Accepts the same optional replacer and space arguments as JSON.stringify:
ko.toJSON(vm, null, 2)// Pretty-printed JSON stringSee Loading & Saving Data for practical patterns.
Extending types with .fn
Section titled “Extending types with .fn”Every observable inherits from a prototype chain you can extend:
subscribable.fn → observable.fn → observableArray.fn → computed.fnAdding a method to ko.observable.fn makes it available on all observables:
ko.observable.fn.log = function (label) { // note: must be function, not arrow, to preserve `this` this.subscribe(v => console.log(label, v)) return this}
const name = ko.observable('TKO').log('name changed:')name('v5') // console: "name changed: v5"Adding to ko.subscribable.fn affects everything — observables, computed, and observable arrays.
Use .fn when the behavior is broadly useful. For one-off logic, prefer a regular function or extender instead.