Javascript引擎会进行这种优化吗?

注意:我已经阅读了一些有关JS引擎优化的文章,但是其中大部分对我来说太技术性,不足以理解到足以解决这个问题。我也知道并非所有引擎都是相同的。我想我会对V8和Rhino的处理特别感兴趣。

如果我创建一个表,然后是行,然后是单元格...然后,我想在所有这些单元格上放置相同的键事件侦听器。

为每个单元创建这些侦听器不仅要花费一定的时间,这对于庞大的表来说可能是很重要的,此外,我还假设每个侦听器函数都是独立存储的,即使每个侦听器函数都是实际上是相同的。

The other key event listener approach which I can use is to put a key event listener on the TABLE, and to work out during the run, on each keydown event, which cell fired this event. I can do this by going

let elementOfInterest = document.activeElement;

"Get the currently focused element in the document" from here.

From my experiments, if you type inside a table cell, this TD does indeed have the focus and is indeed returned by the above call.

这样,我只需要创建一个侦听器,就可以认为它更快,占用更少的内存。唯一(非常)轻微的缺点是,必须花费时间通过上述调用来获取此“活动元素”。而且,很可能,某些事物会以意想不到的方式吸引焦点的风险-显然,如果您想听单元格中文本的更改,则最不容易出错的技术必须是使用连接到该单元格的侦听器。

但是我只是在想:也许Javascript比这更聪明:也许如果您创建100个单独的单元格侦听器,则某些地方会将它们标识为“全部相同”,并且仅在内存中实现一个功能。例如,您通常会期望从Java编译器获得这种优化。

有没有进行过这样的优化?这样的情况下Javascript有多聪明?还是仅仅是“脚本而已”:您所看到的就是所得到的?

评论
  • 一手的触碰
    一手的触碰 回复

    语言本身的语义不允许两个函数表达式“合并”为一个函数,即使它们在功能上是等效的:

    > a = function(){return 'foo'};
    ƒ (){return 'foo'}
    > b = function(){return 'foo'};
    ƒ (){return 'foo'}
    > a === b
    false
    

    此外,当您开始考虑关闭函数时,事情变得更加繁琐(例如,它使用的外部名称)。

    所以不,这不是开箱即用的。

    但是,对于您的用例,有两个优化:

    • As you've found out, you can employ event bubbling and add the event listener on an ancestor element and use event.target (preferably instead of document.activeElement) to figure out where it was originally targeted (and event.currentTarget would be the node the handler is on)
    • If you can't use a common ancestor (tip: you almost always can; document is a valid target), you could define the function once (assuming it doesn't need to close over any dynamically changing variables) and again use event.target, e.g. event.target.dataset to figure out the data you're handling.