JavaScript Magic Method
This script uses Proxy to implement magic methods similar to those in PHP in JavaScript.
Example
You can use it like this:
const Foo = magicMethods(class Foo { constructor () { this.bar = 'Bar' } __get (name) { return `[[${name}]]` } }) const foo = new Foo foo.bar // "Bar" foo.baz // "[[baz]]"
If you are using a JavaScript compiler like Babel and have decorators enabled , you can also use the magicMethods function as a decorator:
@magicMethods class Foo { // ... }
Supporting magic methods
Given a class Class and instance, the following are the magic methods supported by this script:
__get(name)
Called when trying to access instance[name] and name is not an attribute in instance.
Note: In PHP, checking whether name exists in an instance does not use any custom __isset() method.
__set(name, value)
This method is called when trying to use instance[name] = ... and instance does not set the name attribute.
__isset(name)
This method is called when trying to check whether name exists by calling name in instance.
__unset(name)
This method is called when trying to unset the name attribute through delete instance[name].
Other methods
The following magic methods are supported through this script, but are not supported in PHP:
static __getStatic(name)
Similar to __get(), but it is used in Class instead of instance.
static __setStatic(name, value)
Similar to __set(), but used in Class instead of instance.
Why is magic method X not supported?
They are either unnecessary or impractical:
__construct() No, JavaScript already has a constructor.
__destruct(): There is no hook mechanism for object destruction in JavaScript.
__call(): Contrary to PHP, methods are like properties in JavaScript and are first obtained via __get(). To implement __call(), you simply return a function from get().
__callStatic(): Similar to __call(), but with __getStatic().
__sleep(), __wakeup(): JavaScript does not have built-in serialization and deserialization. You can use JSON.stringify() and JSON.parse(), but they have no mechanism to automatically trigger any methods.
__toString() There is already a counterpart to JavaScript's toString()
__invoke(): If you try to call a non-function object, JavaScript will throw an error, which is unavoidable.
__set_state(): There is no equivalent to var_export() in JavaScript.
__clone(): Hook for built-in cloning functionality in JavaScript.
__debugInfo(): Unable to hook into console.log() output.
Can I extend a class using magic methods?
Yes, to a certain extent:
class Bar extends Foo {} // 或者,如果类 Bar 本身包含魔术方法: const Bar = magicMethods(class Bar extends Foo { // ... })
But unfortunately, you cannot access properties in the parent class from the subclass:
const Foo = magicMethods(class Foo { __get() { return this.bar() } }) class Bar extends Foo { bar() { return 'value' } } // 这个 *不会* 调用 B 的 bar() 方法,而是抛出一个类型错误: (new Bar).something
Recommended Tutorial: "JS Tutorial"
The above is the detailed content of Use PHP-like magic methods in JS. For more information, please follow other related articles on the PHP Chinese website!