• There is currently a conversation going in that respect - Serial.on() issues - which is actually more a about this, context classes, objects (instances of classes), functions, methods, callbacks, etc.

    Javascript has a bit a quirky looking way of instantiating an object from a given class: issuing var inst1 = new MyFunction() makes MyFunction() a class definition - or constructor function - that defines - and constructs - (usally the state of) an object - hence the convention of starting Uppercase. Issuing it a second time var inst2 = new MyFunction() creates actually a second, different instance - but with the same properties - state (and behavior).

    Invoking a capability, function, or behavior of that class of objects is then more suitably called invoking a method. Defining methods (behavior) is done by assigning functions to the prototype of the (state) defining function.

    To make it more obvious, lets, call the "MyFunction" a "Person", and provide it with a name 'when born' / created / instantiated:

    var Person = function(name) {
      this.name = name;
    };
    

    Now we provide a behavior to the Person - class of instances:

    Person.prototype.introduceYourself = function() {
      console.log("Hi, my name is " + this.name);
    };
    

    Creating susan and mark and ask them to introduce themselves would then go like this - notice the 'politically not so correct all lower case beginning, but convention complying useful distinction of instance vs. class casing:

    var susan = new Person("Susan");
    var mark = new Person("Mark");
    susan.introduceYourself(); // ---> console shows: Hallo, my name is Susan
    mark.introduceYourself(); // ---> console shows: Hallo, my name is Mark
    

    Note that we had to make the definition only once as a class, but get multiple instances with same state - .name - and behavior - .introducesYourself().

    Unfortunately, the way (most) modules are built and used is the way of singleton. Singleton means: there can exists only / exactly (math.) one instance of that class (so not really a class, because what is a class with one member...). Bit what do you do when you have multiple sensors, and the sensor is made available / connectable via a module that is thinking 'in singleton' (only)?

    Sometimes, you get away by storing the module in a variable and invoke it several times with connect. This works though only when the module is built in a particular way and returning the instance from the constructor function. (Depending how the require("moduleName") is implemented (with or without caching), instead of storing the module reference in a variable, you just repeat the require(...) with no significant performance penalty.)

    You can instantiate objects within other object instantiations... nothing wrong with that. It just creates dependencies - which you may have anyway. A less intertwined approach would be to create the containing object with null values for the contained objects first, and then assign the object instance to in a separate step, where you compose the complete containing object (or you go very sophisticated and use a micro / pico container supporting IoC / DI ... pico has nothing to do with Espruino Pico except that it is a smaller version of a bigger thing...)

    In order to access properties - state and behavior - of a contained object, you can call the objects nested - containingObj.containedObj1.getTemperature(); - which is not the best from an oo point of view. You rather add a facade or delegate method .getTemperature() - ContainingObj.prototype.getTemperature = function() { return this.containedObj1.getTemperature(); }; - to the containing object. With that you can hide the implementation of ContainingObj and you can change it at a later time without having to change where and how it is used (so far).

About

Avatar for allObjects @allObjects started