3 回答
TA贡献1830条经验 获得超9个赞
这是我创建可调用对象的方法,这些对象正确引用其对象成员,并保持正确的继承,而不会弄乱原型。
只是:
class ExFunc extends Function {
constructor() {
super('...args', 'return this.__call__(...args)');
return this.bind(this);
}
// Example `__call__` method.
__call__(a, b, c) {
return [a, b, c];
}
}
扩展此类并添加一个__call__方法,更多信息......
代码和注释中的解释:
// A Class that extends Function so we can create
// objects that also behave like functions, i.e. callable objects.
class ExFunc extends Function {
constructor() {
// Here we create a dynamic function with `super`,
// which calls the constructor of the parent class, `Function`.
// The dynamic function simply passes any calls onto
// an overridable object method which I named `__call__`.
// But there is a problem, the dynamic function created from
// the strings sent to `super` doesn't have any reference to `this`;
// our new object. There are in fact two `this` objects; the outer
// one being created by our class inside `constructor` and an inner
// one created by `super` for the dynamic function.
// So the reference to this in the text: `return this.__call__(...args)`
// does not refer to `this` inside `constructor`.
// So attempting:
// `obj = new ExFunc();`
// `obj();`
// Will throw an Error because __call__ doesn't exist to the dynamic function.
super('...args', 'return this.__call__(...args)');
// `bind` is the simple remedy to this reference problem.
// Because the outer `this` is also a function we can call `bind` on it
// and set a new inner `this` reference. So we bind the inner `this`
// of our dynamic function to point to the outer `this` of our object.
// Now our dynamic function can access all the members of our new object.
// So attempting:
// `obj = new Exfunc();`
// `obj();`
// Will work.
// We return the value returned by `bind`, which is our `this` callable object,
// wrapped in a transparent "exotic" function object with its `this` context
// bound to our new instance (outer `this`).
// The workings of `bind` are further explained elsewhere in this post.
return this.bind(this);
}
// An example property to demonstrate member access.
get venture() {
return 'Hank';
}
// Override this method in subclasses of ExFunc to take whatever arguments
// you want and perform whatever logic you like. It will be called whenever
// you use the obj as a function.
__call__(a, b, c) {
return [this.venture, a, b, c];
}
}
// A subclass of ExFunc with an overridden __call__ method.
class DaFunc extends ExFunc {
get venture() {
return 'Dean';
}
__call__(ans) {
return [this.venture, ans];
}
}
// Create objects from ExFunc and its subclass.
var callable1 = new ExFunc();
var callable2 = new DaFunc();
// Inheritance is correctly maintained.
console.log('\nInheritance maintained:');
console.log(callable2 instanceof Function); // true
console.log(callable2 instanceof ExFunc); // true
console.log(callable2 instanceof DaFunc); // true
// Test ExFunc and its subclass objects by calling them like functions.
console.log('\nCallable objects:');
console.log( callable1(1, 2, 3) ); // [ 'Hank', 1, 2, 3 ]
console.log( callable2(42) ); // [ 'Dean', 42 ]
进一步说明bind:
function.bind()工作很像function.call(),他们共享一个类似的方法签名:
fn.call(this, arg1, arg2, arg3, ...);更多关于mdn
fn.bind(this, arg1, arg2, arg3, ...);更多关于mdn
在第一个参数中重新定义this函数内的上下文。其他参数也可以绑定到值。但是,在call立即使用绑定值调用函数的情况下,bind返回一个“异国情调”的函数对象,该对象透明地包装原始函数,this并预设任何参数。
所以当你定义一个函数时bind,它的一些参数:
var foo = function(a, b) {
console.log(this);
return a * b;
}
foo = foo.bind(['hello'], 2);
只使用其余参数调用绑定函数,其上下文是预设的,在本例中为['hello']。
// We pass in arg `b` only because arg `a` is already set.
foo(2); // returns 4, logs `['hello']`
TA贡献1786条经验 获得超13个赞
您可以使用(也许)陷阱将Smth实例包装在Proxy中:applyconstruct
class Smth extends Function {
constructor (x) {
super();
return new Proxy(this, {
apply: function(target, thisArg, argumentsList) {
return x;
}
});
}
}
new Smth(256)(); // 256
添加回答
举报
