javascript - 最佳实践 : functions within loops

标签 javascript function loops

我得到了以下完美运行的代码。它的作用是:在表格中,当您将鼠标悬停在任何表格单元格上时,它会突出显示相应的表格标题单元格和表格第一列单元格。

  // Row & Column Highlight
 (function() {

     var gridCellRow = null,
         gridCellCol = null,
         tableElement = document.getElementsByClassName('inner_table');
     for (var i = 0, len_i = tableElement.length; i < len_i; i++) {
         if (tableElement[i].getElementsByClassName('row_label_cell').length > 0) {
             var gridCell = tableElement[i].getElementsByClassName('input_cell');
             for (var j = 0, len_j = gridCell.length; j < len_j; j++) {
                 function gridCellParents(currentCell) {
                     return gridCellRow = currentCell.parentNode.firstElementChild,
                         gridCellCol = currentCell.parentNode.parentNode.rows[0].cells[currentCell.cellIndex];
                 }
                 gridCell[j].addEventListener('mouseover', (function() {
                     gridCellParents(this);
                     gridCellRow.classList.add('highlight');
                     gridCellCol.classList.add('highlight');
                 }));
                 gridCell[j].addEventListener('mouseout', (function() {
                     gridCellRow.classList.remove('highlight');
                     gridCellCol.classList.remove('highlight');
                 }));
             }
         }
     }

 }());

但是,JSHint 告诉我,

for (var j = 0, len_j = gridCell.length; j < len_j; j++) {
 function gridCellParents(currentCell) {
     return gridCellRow = currentCell.parentNode.firstElementChild,
         gridCellCol = currentCell.parentNode.parentNode.rows[0].cells[currentCell.cellIndex];
 }

不是最佳实践“函数声明不应放在 block 中。使用函数表达式或将语句移动到外部函数的顶部。”

还有

gridCell[j].addEventListener('mouseover', (function() {
gridCellParents(this);
gridCellRow.classList.add('highlight');
gridCellCol.classList.add('highlight');
}));
gridCell[j].addEventListener('mouseout', (function() {
    gridCellRow.classList.remove('highlight');
    gridCellCol.classList.remove('highlight');
}));
}

不是最佳实践“不要在循环中创建函数。”

那么我如何根据最佳实践正确地构建整个功能?

最佳答案

Function deceleration shouldn't be within loops because it makes no sense to re-create the same function over and over again, in a "continuous flow" (unlike other situation where the same function might be created again, in a more complex code). The main reason is because of hoisting and it strongly goes against javascript principles to write functions declarations inside loops.

一个很好的起点,代码更有序:

     // Row & Column Highlight
(function() {
    var gridCellRow,
        gridCellCol,
        gridCell,
        tableElement = document.getElementsByClassName('inner_table');   

    function gridCellParents(currentCell) {
        gridCellRow = currentCell.parentNode.firstElementChild,
        gridCellCol = currentCell.parentNode.parentNode.rows[0].cells[currentCell.cellIndex];
    }

    function onMouseEnter() {
        gridCellParents(this);
        gridCellRow.classList.add('highlight');
        gridCellCol.classList.add('highlight');
    }

    function onMuoseLeave() {
        gridCellRow.classList.remove('highlight');
        gridCellCol.classList.remove('highlight');
    }


    for (var i = 0, len_i = tableElement.length; i < len_i; i++) {
        if (tableElement[i].getElementsByClassName('row_label_cell').length > 0) {
            gridCell = tableElement[i].getElementsByClassName('input_cell');                    
            for (var j = 0, len_j = gridCell.length; j < len_j; j++) {
                gridCell[j].addEventListener('mouseenter', onMouseEnter);
                gridCell[j].addEventListener('mouseleave', onMuoseLeave);
            }
        }
}}());

如您所见,我已将您的事件修改为 mousentermouseleave这可能更适合您的需求并且对整体性能更好。


更新 - 委托(delegate)版本:

 // Row & Column Highlight
(function() {
    var gridCell,
        tableElement = document.querySelectorAll('.inner_table');   

    function getCellParents(cell){
        return {
            row : cell.parentNode.firstElementChild,                       // row
            col : cell.parentNode.parentNode.rows[0].cells[cell.cellIndex] // col
       }; 
    }

    function updateGridCellParents(cell, state) {
        state = state ? 'add' : 'remove';

        var parents = getCellParents(cell);

        parents.row.classList[state]('highlight');
        parents.col.classList[state]('highlight');
    }

    funciton checkTarget(target){
        // make sure the element is what we expected it to be
        return target.className.indexOf('input_cell') != 0;
    }

    function onMouseEvents(e){
        checkTarget(e.target) && updateGridCellParents(e.target, e.type == "mouseover");
    }

    document.body.addEventListener('mouseover', onMouseEvents);
    document.body.addEventListener('mouseout', onMouseEvents);
})();

关于javascript - 最佳实践 : functions within loops,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36957566/

相关文章:

C++ 循环重复代码

java - 使用 ArrayList 而不是数组来避免使用普通的 for 循环

javascript - 使用位于动画背景上方的 Bootstrap 3 获取网页内容

javascript - 有没有一种好方法可以在多个地方设置 assert.expect(n) ?

javascript - 如果缺少脚本则跳过函数

java - For 循环和数字的整除性

javascript - 如何处理两个javascript事件?

javascript - 在新选项卡中打开网页是否被视为弹出窗口?

c++ - 发送一行二维数组作为参数

function - PL/SQL函数错误-PLS-00103 : Encountered the symbol “IS”