Extending Functions with ES6 Classes: Understanding 'this' and Closure Tricks
Extending special objects in ES6 allows for inheritance from functions, enabling them to be called as functions. However, implementing the logic for such calls requires careful consideration of the 'this' reference.
By default, when a method is called on a class instance, 'this' points to the instance itself. However, when a function is called directly, 'this' refers to the global object (e.g., window). To address this, we have two options:
1. Hardcoding Data in Constructor:
The 'super' call can invoke the Function constructor, expecting a code string. To access instance data, we can hardcode it:
class Smth extends Function { constructor(x) { super("return " + JSON.stringify(x) + ";"); } }
2. Closure and Closure Wrappers:
For a more flexible solution, we need to create a closure that assigns instance data to the returned function:
class Smth extends Function { constructor(x) { function smth() { return x; } Object.setPrototypeOf(smth, Smth.prototype); return smth; } }
To abstract this functionality, we can introduce an 'ExtensibleFunction' class:
class ExtensibleFunction extends Function { constructor(f) { return Object.setPrototypeOf(f, new.target.prototype); } }
Subclasses can then inherit from ExtensibleFunction:
class Smth extends ExtensibleFunction { constructor(x) { super(function() { return x; }); } }
Using arrow functions or named functions can also provide alternative approaches, though they may differ in their inheritance behavior.
The above is the detailed content of How to Extend Functions in ES6 Classes: Navigating \'this\' and Closure Techniques. For more information, please follow other related articles on the PHP Chinese website!