A while ago I had got pull request granted by @Gordon to enable the modules mechanisme play nicely oo... with classes... And that is how it looks like for creating a module providing, for example, a Person 'class' (The concatenated string is the source code of the 'class' definition / constructor with prototype extensions and is part of the module code):
Modules.addCached("Person",
'var Person = function(first, last, birthDate) {'
+ ' this.first = first;'
+ ' this.last = last;'
+ ' this.birthDate = birthDate;'
+ '};'
+ 'Person.prototype.about = function() {'
+ ' return ('
+ ' [ this.first , this.last , "is"'
+ ' , new Date().getFullYear() - this.birthDate.getFullYear()'
+ ' ,"years old."].join(" "));'
+ '};'
+ 'exports = Person;'
);
function onInit() {
var Person = require("Person");
var aPerson = new Person("Pico" , "Espruino"
, new Date(new Date().getTime()
- 2 * 366 * 24 * 60 * 60 * 1000)); // now - 2 years in ms
console.log(aPerson.about());
}
On upload, you still get some warning, because the uploader does not find the module in the project / sandbox or on the Web espruino.com/modules, but when it comes to execution in the onInit(); - invocation issued as command in the console - the module - IS there... in the Modules' cache...
How can you get rid of the warning(s)?... explained in the other conversation...
Replace line 16 with these two lines that supply the module name in a variable and thus escape the parsing for modules before upload ...and that get's rid of the upload warning(s):
var personClassModuleName = "Person";
var Person = require(personClassModuleName);
To work the 'proper' way of modules, place the source code into the project / sandbox / modules folder (see Espruino Web IDE setting / cog wheel in top right) as Person.js or - minified - as Person.min.js. Btw, the naming within the module is of no importance: you can make it as short as possible, for example just P for Person. It is of no importance, because the execution happens in a 'closure'.
// Peson.js module defining Person class.
var Person = function(first, last, birthDate) {
this.first = first;
this.last = last;
this.birthDate = birthDate;
};
Person.prototype.about = function() {
return (
[ this.first , this.last , "is"
, new Date().getFullYear() - this.birthDate.getFullYear()
,"years old."].join(" "));
};
exports = Person;
and it works with the oo charm (upload this code and fire it with onInit() in the console):
function onInit() {
var Person = require("Person"); // get hold of class obj / constructor function
var aPerson = new Person("Pico" , "Espruino"
, new Date(new Date().getTime()
- 2 * 366 * 24 * 60 * 60 * 1000)); // now - 2 years in ms
console.log(aPerson.about());
}
Btw, you are not bound to the class name Person. You can call it what ever you want... The module loading mechanism - eval(source) - is in a closure. The module require mechanism allows a mix and match of modules where the module creators used the same name for their class definition INSIDE the module, but in the application context / namespace you can give them any (global) name of your choice, if a name at all, as shown in the next section.
You can even be that brief (in console or code) - no need to hold on to the module / 'Class' object / Constructor (function)... and use the class obj / constructor function anonymously in your application context... just reference by the module name and delivered as object (class object / constructor function) by the module mechanism:
new (require("Person"))("Pico","Espruino", new Date(1.4E12)).about();
Output:
="Pico Espruino is 2 years old."
>
And if you need the Person class / constructor multiple times in various places, you can do it this way:
var p1 = new (require("Person"))("Pico","Espruino", new Date(1.4e12));
//...
var p2 = new (require("Person"))("Original","Espruino", new Date(1.375e12));
//
console.log(p1.about() + " - vs. - " p2.about());
I'm sure you know that the module name can also be a URL pointing to a module on the World Wide Web (with related security implications)... ;-)
Espruino is a JavaScript interpreter for low-power Microcontrollers. This site is both a support community for Espruino and a place to share what you are working on.
A while ago I had got pull request granted by @Gordon to enable the modules mechanisme play nicely oo... with classes... And that is how it looks like for creating a module providing, for example, a Person 'class' (The concatenated string is the source code of the 'class' definition / constructor with prototype extensions and is part of the module code):
On upload, you still get some warning, because the uploader does not find the module in the project / sandbox or on the Web espruino.com/modules, but when it comes to execution in the
onInit();
- invocation issued as command in the console - the module - IS there... in the Modules' cache...How can you get rid of the warning(s)?... explained in the other conversation...
Replace line 16 with these two lines that supply the module name in a variable and thus escape the parsing for modules before upload ...and that get's rid of the upload warning(s):
To work the 'proper' way of modules, place the source code into the project / sandbox / modules folder (see Espruino Web IDE setting / cog wheel in top right) as
Person.js
or - minified - asPerson.min.js
. Btw, the naming within the module is of no importance: you can make it as short as possible, for example justP
forPerson
. It is of no importance, because the execution happens in a 'closure'.and it works with the oo charm (upload this code and fire it with
onInit()
in the console):Btw, you are not bound to the class name
Person
. You can call it what ever you want... The module loading mechanism - eval(source) - is in a closure. The module require mechanism allows a mix and match of modules where the module creators used the same name for their class definition INSIDE the module, but in the application context / namespace you can give them any (global) name of your choice, if a name at all, as shown in the next section.You can even be that brief (in console or code) - no need to hold on to the module / 'Class' object / Constructor (function)... and use the class obj / constructor function anonymously in your application context... just reference by the module name and delivered as object (class object / constructor function) by the module mechanism:
Output:
And if you need the
Person
class / constructor multiple times in various places, you can do it this way:I'm sure you know that the module name can also be a URL pointing to a module on the World Wide Web (with related security implications)... ;-)
PS: Read through related using modules in modules? conversation.