我创建了这个函数,以便我可以将方法链接在一起:
export default function bindable(fn) {
return function boundFn(...args) {
return this === undefined ? fn(...args) : fn(this, ...args);
}
}
它适用于 bind operator .例如,您可以定义一个新函数,例如,
export const flatten = bindable(arrayOfArrays => Array.prototype.concat(...arrayOfArrays));
然后像这样使用它:
[[1,2,3],[4,5,6]]::flatten()
或者像这样:
flatten([[1,2,3],[4,5,6]])
一开始效果很好,直到我意识到如果我像在第二种情况下那样使用它,但是将辅助方法作为模块导入,它会破坏上下文!
import * as Arr from './array-helper-methods';
Arr.flatten([1,2,3]); // `this` is now `Arr`
所以我的问题是:有什么方法可以可靠地检测是否使用绑定(bind)运算符调用函数?
最佳答案
这是绑定(bind)运算符的一个大问题,但尚未解决。但是不,它只适用于方法。如果您想支持两种样式,您只需提供两个版本您的函数。
动态地做这件事很难。不,您无法检测该函数是否是使用 ()
调用的,作为一种方法,是否绑定(bind)了 call
或 apply
等。而您无论如何,真的不应该。
对于你的情况,我会选择
function bindable(fn, isContext) {
return function boundFn(...args) {
return isContext(this) ? fn(this, ...args) : fn(...args);
}
}
export default bindable(bindable, f => typeof f == "function");
然后你可以使用bindable(flatten, Array.isArray)
或者flatten::bindable(Array.isArray)
来flatten
。对于更复杂的情况,您还可以合并函数的参数,即是否 fn.length + 1 == args.length
。
关于javascript - 如何确定函数是用 `.call` 还是 `.apply` 调用的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44372674/