元素声明为变量vs get元素?

时间:2015-12-17 18:11:50

标签: javascript dom

所以我有这个功能,因为我不使用JQuery:

var $ = function(id) {return document.getElementById(id)};

现在让我们说我想在一个函数中使用它来例如删除一个元素的所有孩子:

function clearMessages() {
    while ($("messages").lastChild) {
        $("messages").removeChild($("messages").lastChild);
    }
}

这是"糟糕的代码"与以下相比,这是非常缓慢的:

var messages = $("messages");

function clearMessages() {
    while (messages.lastChild) {
        messages.removeChild(messages.lastChild);
    }
}

?因为每次使用document.getElementById fn时它会运行clearMessages fn几次?

1 个答案:

答案 0 :(得分:1)

这两个示例的第一个问题是它们是对id #messages或DOM元素messages的硬连线引用。通过使id成为参数,在第一个示例中很容易解决。由于它不再特定于邮件,我们还会重命名它:

function emptyById(id) {
    while ($(id).lastChild) {
        $(id).removeChild($(id).lastChild);
    }
}
很明显,一个人不想一遍又一遍地查找元素。除了性能之外,它还是重复且容易出错的。因此,显然应该重写为

function emptyById(id) {
    var elt = $(id);
    while (elt.lastChild) elt.removeChild(elt.lastChild);
}

然而,这种方法的问题在于它混合了两个完全不同的问题:

  1. 查找具有特定ID的元素。

  2. 对此元素执行某些操作(在这种情况下,删除其子元素)。

  3. 实际上,假设您有一个要删除其子项的元素。鉴于上述设计,您不得不说

    emptyById(elt.id)
    

    如果元素没有碰巧有ID,它甚至无法工作。

    因此,遵循第二个示例更好的设计,并通过DOM元素而不是其ID定义接口(稍微重写循环):

    function emptyChildren(elt) {
      var last;
      while (last = elt.lastChild) elt.removeChild(last);
    }
    

    现在,如果你有元素,你只需拨打emptyChildren(elt);如果您有ID,可以拨打emptyChildren($(id))

    这些都不是关于性能的。 getElementById足够快,当你真的只需要调用一次时,如果你调用它十次,就不会注意到 - 当然,假设这不是一个紧密的循环执行一百万次。重要的问题是如何将接口设计为通用且灵活。