javascriptknockout.jsprototypeknockout-components

Knockout Prototype Issue


I would like to understand why knockout behaves differently when a property is a prototype, and especially important, how to avoid it, while still using prototypes.
I want some methods to be overridden because I have a base view model that we are to inherit

The following demonstrates what I mean

JSFIDDLE WITH PROTOTYPE [try typing into the first input box and it will appear in the other]

var viewModel = function(params) {
        this.params =  params;
    };
    viewModel.prototype.text = ko.observable(this.params  && this.params.initialText || '');


ko.components.register('message-editor', {
    viewModel: viewModel,
    template: 'Message: <input data-bind="value: text" /> '
            + '(length: <span data-bind="text: text().length"></span>)'
});
 
ko.applyBindings();
<!-- ko component: "message-editor" -->
<!-- /ko -->
<br />
<!-- ko component: "message-editor" -->
<!-- /ko -->


<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

JSFIDDLE WITHOUT PROTOTYPE [try typing into the first input box and it will not appear in the other]

var viewModel = function(params) {
        this.params =  params;
        this.text = ko.observable(this.params  && this.params.initialText || '');
    };


ko.components.register('message-editor', {
    viewModel: viewModel,
    template: 'Message: <input data-bind="value: text" /> '
            + '(length: <span data-bind="text: text().length"></span>)'
});
 
ko.applyBindings();
<!-- ko component: "message-editor" -->
<!-- /ko -->
<br />
<!-- ko component: "message-editor" -->
<!-- /ko -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

Why are they behaving differently?


Solution

  • In JavaScript, the prototype is used only for functions that are common to each object of that type. All instances can share the same copy of the function because the function, when called, gets the reference to the instance object through this. Knockout observables are not designed to be stored in the prototype because they store data specific to an object instance.