I'm just posting this up here because I had a bunch of questions in a PM and it seems what's needed is a very clear explanation about how classes work in JS.
Hopefully this will be useful:
ES6 Classes aren't magic - they're just a neat way of writing JavaScript functions
Methods
class Color {
mymethod() {}
}
// is the same as
function Color() {}
Color.prototype.mymethod = function(){}
Static Methods
class Color {
static mymethod() {}
}
// is the same as
function Color() {}
Color.mymethod = function(){}
Using them
// to access a METHOD, you need an instance of the class
var color = new Color();
color.mymethod();
// to access a STATIC METHOD, you access the class directly
Color.mymethod();
You can't access a method like you'd access a static method, and you can't access a static method like you'd access a method. They're different and are accessed in different ways.
Using this
this isn't magic either. Looking at this code:
class Color {
sayhi() {
print(this.hello);
}
}
var color = new Color();
color.hello = "Hello";
If you use . to call a function (eg. color.sayhi()) then this is set to the bit before the ., eg color, when sayhi() is called.
color.sayhi(); // prints 'Hello'
Color.prototype.sayhi(); // prints 'undefined' because 'Color.prototype' doesn't contain 'hello'
var a = color.sayhi;
a(); // prints 'undefined' because there wasn't even a '.' - `this` is just set to the global scope
var exports = {};
exports.sayhi = color.sayhi;
exports.sayhi(); // prints 'undefined' because 'exports' doesn't contain 'hello
Similarly, if you make a static function, it won't have access to the class instance via this because in order to call the static function, you're not calling color.function() but Color.function() - and Color is the class, but color is the class instance.
If you call another function - especially with setTimeout/setIntervalthis can get reset:
class Color {
sayhi() {
print(this.hello);
setTimeout(function() {
print(this.hello); // This doesn't work
}, 1000);
}
}
var color = new Color();
color.hello = "Hello";
color.sayhi(); // prints 'Hello', then 'undefined'
There are a bunch of ways to work around it:
// arrow functions
class Color {
sayhi() {
print(this.hello);
setTimeout(() => {
print(this.hello);
}, 1000);
}
}
Using modules and classes
Right now, The Espruino IDE's minification doesn't handle classes well (it just turns them back into ES5 functions). However you can always set it just for whitespace.
But: neither modules nor the exports variable is remotely magic
// Module contents
exports = "Literally anything";
// Main file
var stuff = require("mymodule");
// stuff is now equal to "Literally anything";
// This is exactly the same as
exports = "Literally anything";
var stuff = exports;
// stuff is now equal to "Literally anything";
When you use require("mymodule"), all Espruino does is run your module code, and then replace require("mymodule") with whatever was in the exports variable after the module finished running
So if you do this:
// Module contents
exports.foo = "stuff";
exports = function() {};
function bob() {}
exports.bar = bob;
exports = "The actual thing";
Then just like if you did this to any other variable, require("mymodule") will be equal to "The actual thing", not any of the stuff it was set to before.
Exporting a class
It's super-easy, just do:
// Module contents
class Color {
method() {
}
static staticmethod() {
}
}
exports = Color;
// Main file
var Color = require("mymodule");
Color.staticmethod();
var color = new Color();
color.method();
This is identical to just having it all in one file, without the lines exports = Color; and var Color = require("mymodule");
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.
I'm just posting this up here because I had a bunch of questions in a PM and it seems what's needed is a very clear explanation about how classes work in JS.
Hopefully this will be useful:
ES6 Classes aren't magic - they're just a neat way of writing JavaScript functions
Methods
Static Methods
Using them
You can't access a method like you'd access a static method, and you can't access a static method like you'd access a method. They're different and are accessed in different ways.
Using
this
this
isn't magic either. Looking at this code:If you use
.
to call a function (eg.color.sayhi()
) thenthis
is set to the bit before the.
, egcolor
, whensayhi()
is called.Similarly, if you make a static function, it won't have access to the class instance via
this
because in order to call the static function, you're not callingcolor.function()
butColor.function()
- andColor
is the class, butcolor
is the class instance.If you call another function - especially with
setTimeout/setInterval
this
can get reset:There are a bunch of ways to work around it:
Using modules and classes
Right now, The Espruino IDE's minification doesn't handle classes well (it just turns them back into ES5 functions). However you can always set it just for whitespace.
But: neither modules nor the
exports
variable is remotely magicWhen you use
require("mymodule")
, all Espruino does is run your module code, and then replacerequire("mymodule")
with whatever was in theexports
variable after the module finished runningSo if you do this:
Then just like if you did this to any other variable,
require("mymodule")
will be equal to"The actual thing"
, not any of the stuff it was set to before.Exporting a class
It's super-easy, just do:
This is identical to just having it all in one file, without the lines
exports = Color;
andvar Color = require("mymodule");