我不断看到:
() => execute code
不只是
execute code
在回调中。我没有传递任何参数,所以为什么()=>执行代码有效,但是执行代码却无效?因为函数仅代表几行代码,它们不是同一回事吗?我在其他语言以及使用lambda的Java中也看到了类似的情况
谢谢。
答案 0 :(得分:4)
使用回调是因为需要在将来某个不确定的时刻调用函数-代码需要执行。简单地在javascript中执行代码将始终立即执行它。如果您需要执行一些异步任务并然后执行某些操作,则这无济于事。
例如,setTimeout()
进行回调是因为它需要等待,然后然后做一些事情:
//In about 1500 ms setTimeout will call this ()=>{} function
setTimeout(() => {
console.log("finished")
}, 1500)
能够传递这样的函数非常灵活,因为该函数还可以接受参数和返回值,这些值可以在调用函数时确定。如果没有将代码组织在一个函数中,那将更加困难,甚至不可能。
如果我只是直接传递一个表达式,它将立即执行:
// console.log runs immediately, there's not way to defer it.
setTimeout( console.log("finished")
, 1000)
因此,该函数不仅代表某些代码,还代表可以被称为 的动作。您可以调用它,也可以在特定时间通过setTimeout或HTTP请求之类的其他函数来调用它。
答案 1 :(得分:1)
您看到的是Java语言中的一个函数,称为“箭头函数”,可以编写如下:
如果返回一个操作,则为单行:
const f = (a,b) => return a+b;
或一行代码以进行更多操作:
const f = (a,b) => { c = a + b; return c};
答案 2 :(得分:1)
区别在于() => console.log('execute code')
是一个函数定义,而console.log('execute code')
是一个函数调用。
在调用该函数之前,函数定义体内的代码不会运行。
var double = (num) => console.log(num + num) // function definition, does nothing
double(2) // function invocation, logs 4 to the console
当您将函数定义作为参数传递给函数调用时,您将使传入的函数定义可在调用的函数体内进行访问或调用。
相反,如果您传递一个函数 invocation ,例如,将double(2)
作为另一个函数调用的参数,则您将返回double(2)
的返回值(在此示例中,情况undefined
,因为console.log
没有返回值)在传递给它的函数的主体中可用。
示例:
var double = (num) => console.log(num + num)
var invokeCallbackAfterFiveSeconds = (callback) => {
setTimeout(callback, 5000);
};
//Passing in a function definition below...
invokeCallbackAfterFiveSeconds(() => double(3));
// ^ Will log 6 to the console after a five second delay
//Passing in a function invocation below...
invokeCallbackAfterFiveSeconds(double(4));
// ^ Will log 8 to the console immediately, then do nothing else.
答案 3 :(得分:0)
该功能是必需的,以便知道不应立即执行代码。
如果您愿意使用
myFunction(myArg, window.location.href='https://www.stackoverflow.com');
代替
myFunction(myArg, () => {
window.location.href='https://www.stackoverflow.com';
});
在第一种情况下,该语言无法知道该代码应在以后的某个时刻作为回调执行。 因此,一旦调用方法wich,就会立即执行该操作,从而导致传递布尔布尔值而不是回调函数。在这种情况下,即使调用的函数没有完全运行,也不会立即在执行回调后切换到stackoverflow.com,而是立即打开页面。
简而言之,通过函数可以在以后调用它包含的代码。
通常将带有结果的参数传递给回调,以允许对其进行处理。
答案 4 :(得分:0)
因为如果按照建议的方式进行操作,则代码将立即执行;即当您拨打电话时。
您需要了解
() -> doSomething()
和
doSomething()
表示不同的事情(以后再做,现在再做),并得出不同的值。他们甚至没有相同的类型。假设doSomething()
返回SomeType
:
Supplier<SomeType>
兼容的对象,并且SomeType
兼容的对象。我想您认为如果两种情况都可以使用相同的语法,并且让编译器能够根据上下文确定正确的含义,那将很好。这样做有两个问题:
这将使代码更难理解。当您阅读某人的代码时,您需要知道每个表达式的每个参数是否期望某些具有立即评估语义(例如方法调用)或递延评估语义(例如lambda)的东西。
在1960年代,他们实际上设计并实现了像这样工作的编程语言。 (查找Algol-60并“按名称呼叫”。)这是一个错误。使用名称呼叫 的Algol-60程序很难理解。 AFAIK,此后此错误在任何主流编程语言中都没有再发生。
您仍然需要声明参数是具有立即还是延迟的评估语义。我认为不可能推断出方法声明中需要的内容。