Search code examples
javascriptnode.jssyntaxnats.ionats-jetstream

Where does "has" come from in "this.has" expression?


I was reading Nats-Jetstream documentation that I encountered the following code:

var createModel = require('jetstream').model;

var Shape = createModel('Shape', function() {
    this.has('x', Number);
    this.has('y', Number);
    this.has('width', Number);
    this.has('height', Number);
    this.has('type', Number);
});

I am not sure what does this.has mean? Where does the has come from? How does this code work?


Solution

  • The shape of the library is described in the docs. It has:

    type JetStream : {
        model: (name: String, fn: ModelDefiner) => Model,
    

    So the callback is a ModelDefiner, which is defined here:

    type ModelDefiner : (this: Model) => void
    

    So this is a Model, which is defined here:

    type ModelObject : {
        has: (propertyName: String, PropertyType) => void,
        setScope: (scope: Scope, Callback<Error, void>) => void,
        getValues: () => Object,
        getAddSyncFragment: () => SyncFragment<"add">
    }
    
    -- A Model instance inherits from ModelObject.
    type Model : ModelObject & {
        typeName: String,
        uuid: ObjectUUID,
        scope: Scope | null
    }
    

    As you can see above, a Model extends a ModelObject, and a ModelObject has a has method.

    If you're curious how you would write code that could do this yourself, all you really need is to create an object with a has method, and .call the callback with it.

    class Model {
      has(str, type) {
        console.log('has called with', str, type);
      };
    }
    const createModel = (str, callback) => {
      const model = new Model();
      callback.call(model);
    };
    
    var Shape = createModel('Shape', function() {
        this.has('x', Number);
        this.has('y', Number);
        this.has('width', Number);
        this.has('height', Number);
        this.has('type', Number);
    });