优雅地检测回调函数中事件对象的存在(和类型)或不存在

Elegantly detecting the presence (and type) or absence of an Event Object inside a callback function

我有一个函数,我打算在几个不同的 Events 上触发。

重要的是,函数可以直接调用。

但我需要函数知道它是由哪个事件触发的...或者它是否被直接调用。

我意识到我可以(以某种方式)利用 Event Object 并使用类似的东西:

const myFunction = (e) => {

  if ((e !== undefined) && (e.hasOwnProperty('type')) {

    switch (e.type) {

      case ('click'):      console.log('Click Event');       break;
      case ('mouseover'):  console.log('Mouseover Event');   break;
    }
  }

  else {

    console.log('Separately invoked');
  }
}

这并不可怕,但它比我想要的更冗长而且我不太热衷于通过检查 e 是否都是 not undefined and 有一个特定的 属性... 这似乎是一种非常迂回的方法来验证是否存在 Event Object.

是否有更好的方法来检查 Event Object 的 [存在和类型] 或 [不存在]?

Is there a better way to check for the [presence and type] or [absence] of an Event Object?

原来有

ES2020 引入了 可选链接 ,使用运算符 ?. 在任何时候 returns undefined 如果 链中的任何 属性 - 甚至父对象 - 都找不到。

这意味着在任何

const myFunction = (e) => { [... CODE HERE... ] }

我们可以使用这个:

e?.type

哪个returns:

  • EventObject.type,如果函数参数eEvent Object
  • undefined,如果函数参数 e 是缺少 属性 type
  • 的对象/数据结构
  • undefined,如果函数被调用时没有任何参数

工作示例:

const myDiv = document.querySelector('.myDiv');

const myFunction = (e) => {

  switch (e?.type) {

    case ('click') : console.log('Click Event'); break;
    case ('mouseover') : console.log('Mouseover Event'); break;
    default : console.log('Separately invoked');
  }
}

setInterval(myFunction, 3000);

myDiv.addEventListener('mouseover', myFunction, false);
myDiv.addEventListener('click', myFunction, false);
.myDiv {

  width: 100px;
  height: 100px;
  background-color: rgb(255, 0, 0);
}
<div class="myDiv"></div>


进一步阅读:

您可以使用 optional chaining and nullish coalescing 获取类型或 "direct" 直接调用:

const myFunction = (e) => {
    switch (e?.type ?? "direct") {
        case "click":
            console.log("Click Event");
            break;
        case "mouseover":
            console.log("Mouseover Event");
            break;
        case "direct":
            console.log("Separately invoked");
            break;
        default:
            console.log("Other");
            break;
    }
};

使用内联 case 格式:

const myFunction = (e) => {
    switch (e?.type ?? "direct") {
        case "click":     console.log("Click Event");        break;
        case "mouseover": console.log("Mouseover Event");    break;
        case "direct":    console.log("Separately invoked"); break;
        default:          console.log("Other");              break;
    }
};

或者没有那些相对较新的功能,逻辑 &&||:

const myFunction = (e) => {
    switch ((e && e.type) || "direct") {
        // ...
    }
};