Javascript 事件处理程序的引擎盖下面发生了什么?它是否适用于其他功能?

Javascript 事件处理程序的引擎盖下面发生了什么?它是否适用于其他功能?,javascript,reactjs,ecmascript-6,Javascript,Reactjs,Ecmascript 6,大家好,我只是想了解当我有一个由事件触发的函数时,javascript/react是如何处理发生的事情的。我将展示三个不同的代码段,其中两个有效,一个无效,看看我是否正确理解它们。:) setField(e){console.log(“在setField中,e)} this.setField()}> 这不起作用,因为它将null值传递给期望值的函数,在本例中为e。然而,如果函数只是提交一些已经处于状态的内容,那么这将是一种合理的方式 setField(e){console.log("in se

大家好,我只是想了解当我有一个由事件触发的函数时,javascript/react是如何处理发生的事情的。我将展示三个不同的代码段,其中两个有效,一个无效,看看我是否正确理解它们。:)

setField(e){console.log(“在setField中,e)}
this.setField()}>
这不起作用,因为它将null值传递给期望值的函数,在本例中为e。然而,如果函数只是提交一些已经处于状态的内容,那么这将是一种合理的方式

setField(e){console.log("in setfield", e)}

<select multiple className="form-control" id="sel2" name="sellist2"
      onChange={(e) => this.setField(e)}>
setField(e){console.log(“在setField中,e)}
this.setField(e)}>
这是因为它将事件获取为e,然后将其传递给函数。它如何知道将事件与e关联?在处理html时,此功能是否扩展到其他方面

setField(e){console.log("in setfield", e)}

<select multiple className="form-control" id="sel2" name="sellist2"
      onChange={this.setField}>
setField(e){console.log(“在setField中,e)}
这一个我真的不明白为什么它有效,但它确实有效。我假设它天生知道将事件作为默认值传递给函数。同样,这种内在逻辑是否发生在其他任何地方,可能不一定发生在事件中


再次感谢。我是javascript新手,所以学习javascript的所有idosyncracies很有趣。可悲的是,大部分的学习都是通过调试的挫折来完成的

javascript中的所有函数都可以传递任意数量的参数,即使函数不使用这些参数。例如,以下内容是合法的(如果无用):

function thingThatExpectsZeroParams() {
  console.log('hello');
}

thingThatExpectsZeroParams(1, 2, 3, 4, [5], 'six');
有六条数据被传递到函数中,但由于函数没有对它们做任何处理,因此它们没有发生任何变化。要访问传入的值,只需选择要调用的名称。此名称是函数的本地名称,可以是您想要的任何名称

function callback(event) {
  console.log(event);
}

// I could also just have easily called it something else, and the code would work just as well
// function callback(quesoBurrito) {
//   console.log(quesoBurrito);
// }

callback('hello');
因此,当您设置如下侦听器时:

onChange={() => this.setField()}
将调用您的函数,并传入事件对象。但是,由于函数没有给第一个参数命名,因此无法访问它,当调用this.setField时,也没有传递任何内容

相反,对于此侦听器:

onChange={(e) => this.setField(e)}
将再次调用您的函数,并传入事件对象。这一次,您将该参数命名为“e”,然后可以随意处理它,在本例中,将其转发给setField

当你这样做的时候:

onChange={this.setField}
onChange={() => this.setField()}

你去掉了中间人。将直接调用this.setField,并传入事件对象。据推测,setField预期会发生这种情况,并对它传递的对象执行某些操作。

这并不复杂。分配给onChange的任何Javascript函数都将在适当的时间被调用,并传递一个通常称为
e
的参数。您可以在函数中为该参数指定任何名称(或者根本不声明它),但第一个参数将在那里

因此,当您这样做时:

onChange={this.setField}
onChange={() => this.setField()}
您正在忽略传递给事件处理程序的参数,然后在该事件处理程序中调用
this.setField()
,而该事件处理程序没有将任何参数传递给
setField()
。实际上,实际发生的情况是:

onChange={(e) => this.setField()}
它如何知道将事件与e关联?在处理html时,此功能是否扩展到其他方面

setField(e){console.log("in setfield", e)}

<select multiple className="form-control" id="sel2" name="sellist2"
      onChange={this.setField}>
DOM规范指出,当调用onChange事件处理程序时,它将被传递
e
对象作为第一个参数(无论您是否声明它,它都作为函数的第一个参数)。这就是Javascript中回调的工作方式。回调的调用者决定要传递回调的参数。声明回调时由您决定是否声明参数并使用它。无论您如何声明它,调用方都会传递它

对于本节代码:

onChange={this.setField}
您可以说希望成为onChange事件处理程序的函数是您的
setField()
方法。因此,毫不奇怪,当DOM调用该方法时,它将传递事件对象作为第一个参数,就像上面的示例一样

这一个我真的不明白为什么它有效,但它确实有效。我假设它天生知道将事件作为默认值传递给函数。同样,这种内在逻辑是否发生在其他任何地方,可能不一定发生在事件中


如前所述,DOM规范是指定此事件处理程序的地方。在该函数的定义中,它描述了哪些参数将传递或不传递给注册为该事件处理程序的回调函数。Javascript中的所有回调都是如此。调用方决定将传递给回调的内容。这不是特定于此类型的事件处理程序的。回调在Javascript中有很多地方使用。甚至像
array.filter()
这样的东西也会接受回调,而回调的调用者(在这种情况下是数组对象的实现)决定将哪些参数传递给回调。

您说eventHandler将作为第一个参数传递给e对象。这是否意味着我可以将其他内容传递给对象,但仍然可以访问e?比如:setField(cat){field=e.target.value+cat}@JamesRundle-No。您无法控制传递给回调/事件处理程序的内容。这是在实际调用回调的代码实现的其他地方确定的。那不在你的控制之下。事实就是这样。而且,
e
不会被神奇地定义,除非您将回调的第一个参数命名为
e