字符串化事件对象有效,但实际上是空的

时间:2018-01-02 02:32:09

标签: javascript json dom

我有这个自定义stringify函数,可以处理循环引用:

const customStringify = function (v) {
  return JSON.stringify(v, function(k, v) {
    if (v instanceof Node) {
      return 'Node';
    }
    if (v instanceof Window) {
      return 'Window';
    }
    return v;
  });
};

但如果我用它来串化事件对象:

  window.addEventListener('click', function (ev) {   // MouseEvent
    const v = customStringify(ev);  // {"isTrusted":true}
  });

v就是这样的字符串:

{"isTrusted":true}
很奇怪。我尝试了一些其他自定义字符串化辅助函数,它们都给了我相同的结果。

我看了这个帖子: How to stringify event object?

但我的问题似乎更具体。

1 个答案:

答案 0 :(得分:3)

JSON.stringify忽略不可枚举的属性,MouseEvent的大部分属性(显然)都是不可枚举的:

document.querySelector('button').addEventListener('click', ev => {
  let props = ['isTrusted', 'target', 'clientX', 'clientY', 'layerX', 'layerY'];
  props.forEach(prop => {
    console.log(prop + '?', ev.propertyIsEnumerable(prop));
  });
});
<button>Try it!</button>

您可以按名称调出每个媒体资源,并在将事件移至JSON.stringify之前使其可枚举:

document.querySelector('button').addEventListener('click', ev => {
  let props = ['target', 'clientX', 'clientY', 'layerX', 'layerY'];
  props.forEach(prop => {
    Object.defineProperty(ev, prop, {
      value: ev[prop],
      enumerable: true,
      configurable: true
    });
  });
  console.log(JSON.stringify(ev));
});
<button>Try it again!</button>