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?
CodePudding user response:
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);
});
CodePudding user response:
When curious, it's always good to look at the source, which they've made available. First thing to check since this is a node project would be the package.json -- main is "index". All the exports are going to be defined in libs/index.js.
Looking at libs/index.js line 52, we see where model is defined as an export -- it's a function where you pass in a name and definition that get passed to ModelObject.model; if you scroll back up, you can see that that's included from libs/model_object.js.
Going over to libs/model_object, you can see what the passed definitions field (the lambda function you see in the example code) is used for: definitions.call(typeClass)
. typeClass
is created earlier in the function. If you're unfamiliar with what call does, it lets a function be executed in another object -- the this
you see in the passed function is going to refer to the typeClass
object. Inside of libs/model_object.js, a has function is defined that adds ModelObjectProperties; this.has
is being used to add properties to the ModelObject.
edit: CertainPerformance's answer is probably more clear, refer to that.