慕标琳琳
这是我创建可调用对象的方法,这些对象正确引用其对象成员,并保持正确的继承,而不会弄乱原型。只是: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); // trueconsole.log(callable2 instanceof ExFunc); // trueconsole.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, ...);更多关于mdnfn.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']`