为什么在这里的a
方法中必须在b
之后写入mls
和setTimeout
?箭头功能中是否尚未定义a
和b
?
function f(a, b) {
alert(a + b);
}
// shows 3 after 1 second
Function.prototype.defer = function(mls) {
return (a, b) => setTimeout(this, mls, a, b);
}
f.defer(1000)(1, 2);
答案 0 :(得分:0)
因为f.defer(1000)
返回箭头函数,而箭头函数又以(1,2)
作为参数被调用。此箭头函数正在调用setTimeout
,该{应该使用这些参数function f
和1
来调用相同的2
。 seTimeout
的定义指出,您可以在前两个参数之后将参数传递给回调函数。请参考下面的定义和链接以供参考。
window.setTimeout(function[, delay, param1, param2, ...]);
https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout
答案 1 :(得分:-1)
箭头函数定义了一个函数,然后该函数调用setTimeout(this, mls, a, b)
。也可以写成:
Function.prototype.defer = function(mls){
var that = this;
return function(a,b) {
setTimeout(that, mls, a, b);
}
}
要注意这一点,因为实际上是从defer
返回一个函数。因此,当您调用f.defer(1000)
时,返回值是一个函数-具体来说就是您的箭头函数-然后您在调用{{时,使用值1
和2
调用该函数1}}。
如果不这样做,则不会使用任何参数调用函数。这些参数将传递到最初调用的函数中。
答案 2 :(得分:-1)
setTimeout
采用可变数量的参数。第一个是函数(在这种情况下为this
或f
),第二个是延迟。此后的任何参数在调用时都会传递给要调用的函数。
您的函数f
需要两个参数;如果未通过,则为undefined
。确实确实有“ a
和b
已在箭头函数中定义” ,但它们作用域为箭头函数。如果一个函数调用另一个函数,则不会自动传递其参数。
在此示例中,内部setTimeout
的行为类似于outerWorking
:
const inner = (a, b) => a + b,
outerWorking = (a, b) => inner(a, b),
outerNotWorking = (a, b) => inner();
console.log(outerWorking(2, 3)); // 5
console.log(outerNotWorking(2, 3)); // NaN
因此f.defer(1000)
返回一个包含mls === 1000
和this === f
的新函数。它接受a
和b
,这些尚未在下一个函数调用(使用参数列表(1, 2)
调用箭头函数)中定义。只有当您在a
处传递b
,f.defer(1000)(1, 2)
时,setTimeout(this, mls,a,b)
才会被a === 1
,b === 2
和上面的其他两个绑定调用( this
和delay
)。
或者,它可以写为
Function.prototype.defer = function(mls, a, b){
setTimeout(this, mls, a, b);
};
f.defer(1000, 1, 2)
但是原始的 curried 方法有一个优势,因为您可以简单地从最终调用中分离“延迟函数”:
const add1sDelay = f.defer(1000);
add1sDelay(1, 2);