JavaScript - 将函数调用应用于具有另一个原型的对象
JavaScript - Apply function call to object with another prototype
我面临的任务(实际上是问题)如下。我有一个数组(我们称它为 arr
)。数组的第一个元素是函数,其余元素是参数。例如:
arr = [(a, b) => a + b, 5, 7];
因此,我需要使用参数 5
和 7
调用函数 (a, b) => a + b
。但是,我不想使用 arr[0](...arr.slice(1))
,而是想使用 Function.prototype.apply
和 Function.prototype.call
(如果需要,我也可以使用 Function.prototype.bind
)。所以基本上,我只能访问 arr
一次,不能使用其他变量。此外,我不允许修改 arr
或其属性,或将任何其他数据存储在某处(例如某些全局对象的 属性 等)。这可能吗?
我的尝试
我试图弄清楚,这是我想出的(它不起作用):
Function.prototype.apply.call(this, ...arr);
但是,它会抛出一条错误消息:
Uncaught TypeError: Function.prototype.apply was called on #Global, which is an object and not a function
问题
正确的做法是什么?
instead I want to do it using Function.prototype.apply and Function.prototype.call. Is that even possible?
当然可以,但我们必须重复 arr
:
arr[0].call(...arr)
实例:
const arr = [(a, b) => a + b, 5, 7];
console.log(arr[0].call(...arr));
如果函数需要特定的 this
,那将不起作用,但是您的函数不需要,原因有两个,其中一个就足够了:1. 它是一个箭头函数,所以它不不管我们用什么 this
来称呼它,它都会关闭创建它的地方;和 2. 无论如何它都不使用 this
。
话虽如此,最好还是给自己一个辅助函数来代替它。
您可以使用解构将 arr
数组的元素作为变量,然后使用索引 1-N
处的元素调用索引 0
处的函数
let arr = [(a, b) => a + b, 5, 7];
let [fn, a, b] = arr;
console.log(fn(a, b));
对于索引 1-N 处的任意数量的元素,您可以使用剩余元素
let arr = [(a, b) => a + b, 5, 7];
let [fn, ...rest] = arr;
console.log(fn.apply(null, rest));
或者,使用 Function
,模板文字将数组转换为字符串,.replace()
与 RegExp
/\s/g
与 .replace()
删除 space字符,.match()
和RegExp
/(\(.*\)=>[^,]+(?=,))|[^,]{1}[^]+/g
捕获箭头函数,取反第一个逗号不是箭头函数的字符和第一组捕获的箭头函数,可以参考arr
once and not create additional variables save for immediately invoked 箭头函数参数
let arr = [(a, b) => a + b, 5, 7];
console.log(
(([a, b]) => new Function(`return (${a})(${b.split(/,/)})`)())
(`${arr}`.replace(/\s/g, "").match(/(\(.*\)=>[^,]+(?=,))|[^,]{1}[^]+/g))
)
我面临的任务(实际上是问题)如下。我有一个数组(我们称它为 arr
)。数组的第一个元素是函数,其余元素是参数。例如:
arr = [(a, b) => a + b, 5, 7];
因此,我需要使用参数 5
和 7
调用函数 (a, b) => a + b
。但是,我不想使用 arr[0](...arr.slice(1))
,而是想使用 Function.prototype.apply
和 Function.prototype.call
(如果需要,我也可以使用 Function.prototype.bind
)。所以基本上,我只能访问 arr
一次,不能使用其他变量。此外,我不允许修改 arr
或其属性,或将任何其他数据存储在某处(例如某些全局对象的 属性 等)。这可能吗?
我的尝试
我试图弄清楚,这是我想出的(它不起作用):
Function.prototype.apply.call(this, ...arr);
但是,它会抛出一条错误消息:
Uncaught TypeError: Function.prototype.apply was called on #Global, which is an object and not a function
问题
正确的做法是什么?
instead I want to do it using Function.prototype.apply and Function.prototype.call. Is that even possible?
当然可以,但我们必须重复 arr
:
arr[0].call(...arr)
实例:
const arr = [(a, b) => a + b, 5, 7];
console.log(arr[0].call(...arr));
如果函数需要特定的 this
,那将不起作用,但是您的函数不需要,原因有两个,其中一个就足够了:1. 它是一个箭头函数,所以它不不管我们用什么 this
来称呼它,它都会关闭创建它的地方;和 2. 无论如何它都不使用 this
。
话虽如此,最好还是给自己一个辅助函数来代替它。
您可以使用解构将 arr
数组的元素作为变量,然后使用索引 1-N
0
处的函数
let arr = [(a, b) => a + b, 5, 7];
let [fn, a, b] = arr;
console.log(fn(a, b));
对于索引 1-N 处的任意数量的元素,您可以使用剩余元素
let arr = [(a, b) => a + b, 5, 7];
let [fn, ...rest] = arr;
console.log(fn.apply(null, rest));
或者,使用 Function
,模板文字将数组转换为字符串,.replace()
与 RegExp
/\s/g
与 .replace()
删除 space字符,.match()
和RegExp
/(\(.*\)=>[^,]+(?=,))|[^,]{1}[^]+/g
捕获箭头函数,取反第一个逗号不是箭头函数的字符和第一组捕获的箭头函数,可以参考arr
once and not create additional variables save for immediately invoked 箭头函数参数
let arr = [(a, b) => a + b, 5, 7];
console.log(
(([a, b]) => new Function(`return (${a})(${b.split(/,/)})`)())
(`${arr}`.replace(/\s/g, "").match(/(\(.*\)=>[^,]+(?=,))|[^,]{1}[^]+/g))
)