javascript - 如何确定函数是用 `.call` 还是 `.apply` 调用的?

标签 javascript this babeljs

我创建了这个函数,以便我可以将方法链接在一起:

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]])

Babel REPL

一开始效果很好,直到我意识到如果我像在第二种情况下那样使用它,但是将辅助方法作为模块导入,它会破坏上下文!

 import * as Arr from './array-helper-methods';
 Arr.flatten([1,2,3]); // `this` is now `Arr`

所以我的问题是:有什么方法可以可靠地检测是否使用绑定(bind)运算符调用函数?

最佳答案

这是绑定(bind)运算符的一个大问题,但尚未解决。但是不,它只适用于方法。如果您想支持两种样式,您只需提供两个版本您的函数。

动态地做这件事很难。不,您无法检测该函数是否是使用 () 调用的,作为一种方法,是否绑定(bind)了 callapply 等。而您无论如何,真的不应该。

对于你的情况,我会选择

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/

相关文章:

jquery - 'This' 检查 Jquery

node.js - "require external module babel-register"执行时间长

javascript - Meteor 找不到重新导出的模块

javascript - nodemon,babel-node : how to set environment variable?

javascript - 如何自定义文本区域以使用户能够像 MS Word 列一样书写

JavaScript 引用错误 : Value is not defined

javascript - 在 memoize 的 js 实现中使用 apply 时, 'this' 是什么?

javascript - 无法使用 "this"定义方法

javascript - 水车 slider 字幕问题

javascript - 从 Master JS 菜单运行其他 JS