meta.js offers meta-programming skills for Javascript and make it more like a class-based language.
We suggest to define class by es6 syntax, and use .new factory method to create instance.
class Person {}
let p = Person.new();
class Animal {
constructor(name) {
this.name = name;
}
walk() {
console.log(`${this.name} walks`);
}
}
let man = Animal.new("jtwang");
man.class.name; // => "Animal"
Animal.instanceMethods; // => ["constructor", "walk"]
Methods in superclass are not included.
man.methods; // => ["constructor", "walk"]
Methods in superclass are not included. Can add them if in need.
man.instanceVariables; // => ["name", "_origin"]
_origin is an inner variable of meta.js. Will explain it later.
class Cat extends Animal {
constructor(name) {
super(name);
}
}
let kitty = Cat.new("kitty");
kitty.class.superclass.name; // => "Animal"
Javascript cannot open class like Ruby, so use defineMethod instead.
Cat.defineMethod("meow", function() {
console.log(`${this.name} meow`);
});
kitty.meow(); // => "kitty meow"
Someone may ask what's the difference between it and Cat.prototype.meow = function() {...}
. It hides the prototype and defines methods in a more meaningful way, which is encouraged by es6 standard.
Cat.deleteMethod("meow");
kitty.meow(); // => error!
It does not delete method in superclass. Can add the function if in need.
Animal.aliasMethod("oldWalk", "walk");
Animal.defineMethod("walk", function() {
console.log("start walk");
this.oldWalk();
console.log("end walk");
});
man.walk(); // => "start walk\n jtwang walks\n end walk"
This example use alias to implement around method, and can be used in AOP.
class Entity {
methodMissing(name, args) {
console.log(`call method ${name} with args: ${args.join(',')}`);
}
responedToMissing(name) {
return true;
}
}
let e = Entity.new();
e.arbitrarymethod(1,2,3); // => "call method arbitrarymethod with args: 1,2,3"
It's implemented by Proxy in es6, so use new Entity()
will lose this feature. You can also use e._origin
to get the object behind proxy.
Make sure to override responedToMissing
method for method names which handled in methodMissing function.
The code is easy in meta.js, and feel free to raise issues or pull request for any problems and suggestions.