This script implements some of PHP's magic methods for JavaScript classes, using a Proxy.
The fork contains a modification that makes the __get method usable recursively like in php
You can use it like this:
const Foo = magicMethods(class Foo {
constructor () {
this.bar = 'Bar'
}
__get (name) {
switch (name){
case 'firstName': return 'Petra';
case 'lastName': return 'Mustermann';
// __get also fires within __get
case 'fullName': return this.firstName + ' ' + this.lastName;
}
console.error('undefined prop ' + name);
}
})
const foo = new Foo
foo.fullName; // Petra Mustermann
If you're using a JavaScript transpiler like Babel with decorators enabled, you can also use the magicMethods
function as a decorator:
@magicMethods
class Foo {
// ...
}
Given a class Class
and an instance
of it, the following are the magic methods supported by this script:
Called when trying to access instance[name]
where name
is not an existing property of instance
.
Attention: As in PHP, the check if name
exists in instance
does not use any custom __isset()
methods.
Called when trying to do instance[name] = ...
where name
is neither set as a property of instance
.
Called when trying to check existance of name
by calling name in instance
.
Called when trying to unset property name
by calling delete instance[name]
.
The following magic methods are made available by this script, but are not supported in PHP:
Like __get()
, but in the Class
instead of the instance
.
Like __set()
, but in the Class
instead of the instance
.
They are either not necessary or not practical:
__construct()
is not needed, there's JavaScript'sconstructor
already.__destruct()
: There is no mechanism in JavaScript to hook into object destruction.__call()
: Functions are first-class objects in JavaScript. That means that (as opposed to PHP) an object's methods are just regular properties in JavaScript and must first be obtained via__get()
to be invoked subsequently. So to implement__call()
in JavaScript, you'd simply have to implement__get()
and return a function from there.__callStatic()
: As in__call()
, but with__getStatic()
.__sleep()
,__wakeup()
: There's no builtin serialization/unserialization in JavaScript. You could useJSON.stringify()
/JSON.parse()
, but there's no mechanism to automatically trigger any methods with that.__toString()
is already present in JavaScript'stoString()
__invoke()
: JavaScript will throw an error if you'll try to invoke a non-function object, no way to avoid that.__set_state()
: There's nothing likevar_export()
in JavaScript.__clone()
: There's no builtin cloning functionality in JavaScript that can be hooked into.__debugInfo()
: There's no way to hook intoconsole.log()
output.
Yes:
// `Bar` inherits magic methods from `Foo`
class Bar extends Foo {}
Or, if class Bar
contains magic methods itself:
const Bar = magicMethods(class Bar extends Foo {
// You may define `Bar`'s magic methods here
})