0

我继续看到:

() => execute code

而不仅仅是

execute code 

在回调中。我没有传入任何参数,那么为什么 () => 执行代码有效但执行代码无效?因为一个函数只代表几行代码,所以它们不是一回事吗?我在其他语言中看到类似的东西,比如使用 lambda 的 java

谢谢你。

4

5 回答 5

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 请求调用。

于 2019-05-19T05:28:22.153 回答
1

你看到的是 Javascript 中的一个函数,叫做箭头函数,可以写成如下:

如果返回一个操作,则为单行:

const f = (a,b) => return a+b;

或用于更多操作的行块:

const f = (a,b) => { c = a + b; return c};
于 2019-05-19T05:32:00.233 回答
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

当您将函数定义作为参数传递给函数调用时,您正在使传入的函数定义可用于在被调用函数的主体内访问或调用。

相反,如果您将一个函数调用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.

于 2019-05-19T06:06:42.407 回答
0

需要该函数才能知道不应立即执行代码。
如果你会使用

myFunction(myArg, window.location.href='https://www.stackoverflow.com');

代替

myFunction(myArg, () => {   
    window.location.href='https://www.stackoverflow.com';
});

在第一种情况下,该语言无法知道代码应该在稍后作为回调执行。因此,只要调用该方法就会执行它,这会导致传递布尔值而不是回调函数。在这种情况下,即使调用的函数没有完全运行,页面也会立即打开,而不是在作为回调执行后切换到 stackoverflow.com。

简而言之,传递一个函数允许稍后通过调用它来运行它包含的代码。

通常将带有结果的参数传递给回调以允许处理这些结果。

于 2019-05-19T05:34:14.133 回答
0

因为如果你按照你建议的方式去做,代码会立即执行;即当您拨打电话时。

你需要明白这一点

() -> doSomething()

doSomething()

意味着不同的事情(以后做与现在做)并评估不同的值。他们甚至没有相同的类型。假设doSomething()返回SomeType

  • Supplier<SomeType>lambda 表达式的计算结果为与和兼容的对象
  • 该调用评估为与 兼容的对象SomeType

我想您认为如果您可以对两种情况使用相同的语法会很好,并让编译器根据上下文确定正确的含义。这有两个问题:

  1. 这会使代码更难理解。当您阅读某人的代码时,您需要知道每个表达式的每个参数是否期望具有立即评估语义(如方法调用)或延迟评估语义(如 lambda)的东西。

    早在 1960 年代,他们实际上设计并实现了一种像这样工作的编程语言。(查找 Algol-60 并“按名称呼叫”。)这是一个错误。使用名称调用的 Algol-60 程序很难理解。AFAIK,从那时起,任何主流编程语言都没有重复过这个错误。

  2. 您仍然需要声明参数是否具有立即或延迟评估语义。我认为不可能推断出方法声明中需要哪个。

于 2019-05-19T05:34:55.547 回答