JSLint用于向后循环

时间:2015-06-04 23:18:59

标签: javascript jslint

道格拉斯·克罗克福德,因此,JSLint真的不喜欢循环。大多数时候我同意,并使用[].forEachObject.keys(obj)来迭代数组或词典。

但是,有些情况下内置函数并不比任何合理意义上的for循环更好(据我所知),我不喜欢在我的JSLints上发出警告。

一个这样的情况是,当一个人在画布上有一堆物品时。绘图时,您希望向前遍历数组,但是当点击测试鼠标单击时,您需要向后迭代。 E.g。

// ...
drawItems = function () {
    objects.forEach(drawItem);
},
hitTest = function (x, y) {
    var i;
    for (i = objects.length - 1; i >= 0; i -= 1) {
        if (test(objects[i], x, y)) {
            return objects[i];
        }
    }
}
// ...

我可以想出几种通过测试的方法,但它们都很笨重。 E.g。

hitTest = function (x, y) {
    var item;

    objects.reverse();
    objects.some(function (v) {
        if (test(v)) {
            item = v;
            return true;
        }
    });
    objects.reverse();
    return item;
}

hitTest = function (x, y) {
    return objects.reduceRight(
        function (prev, curr) {
            return prev || (
                test(curr, x, y)
                    ? curr
                    : prev
            );
        },
        undefined
    );
}

哪个会愉快地传递JSLint,但是,说实话,看起来很恶心。我不喜欢" hacking"我的代码只是让它通过测试。

除了选择"容忍声明"选项(因为这影响了其余代码的lint),我如何处理这个问题,同时避免浪费操作,如反转或复制数组?

3 个答案:

答案 0 :(得分:2)

进入一个有趣的reverse - 免费替代修复here - 请参阅第3和第3章。第四 - 今天看别的东西。很容易从jQuery的each交换到forEachevery。无论如何你必须得到原始for的长度,所以实际上很干净,虽然有点时髦。

/*jslint white:true, devel:true */
var a = [3,4,5,6], max = a.length-1;
a.forEach(function (ignore, i) {
    "use strict";
    console.log(a[max-i]);
});

我很少担心性能问题,因为您每次迭代都要抽出两次元素,一次是a[max-i]一次{{3} },虽然可能是' sa forEach's callback's (here, throwaway) third argument

仅针对指标使用forEach是什么引发了行家警告。讽刺,自micro-optimization concern以来,所以我不确定他是否喜欢这个"修复"要么 - 我们都没有人回答你的问题" Crockford has shown a stark dislike for hipsters in the past"。诱惑为meta-question;这是一个很好而有趣的问题,但你并不总能在这个清单上找到一个好的答案。

但这是一个非常(看似敏感?)干净的解决方法。

答案 1 :(得分:1)

由于我认为你不应该对你的代码进行去优化只是为了让一个毫无意义的警告消失,这里有一些你可以解决的问题:

  1. 忽略误导的警告。
  2. 切换到jsHint,它允许您instruct jsHint to ignore certain sections of code(带有嵌入式注释)。
  3. 在函数或方法中隔离jsLint不满意的代码,因此警告仅在整个源中发生一次,而不是每次都要进行反向遍历。
  4. 例如,这里是反向遍历函数:

    // traverse an array in reverse order
    // if the callback returns true, iteration will be stopped
    function reverseForEach(array, fn) {
        for (var i = array.length - 1; i >= 0; i--) {
            if (fn(array[i], i, array) === true) {
                return;
            }
        }
    }
    

    或者,作为Array原型的方法:

    // traverse an array in reverse order
    // if the callback returns true, iteration will be stopped
    Array.prototype.reverseForEach = function(fn) {
        for (var i = this.length - 1; i >= 0; i--) {
            if (fn(array[i], i, this) === true) {
                return;
            }
        }
    }
    

答案 2 :(得分:0)

您可以slice数组,以便您的hitTest没有任何潜在的副作用。

hitTest = function (x, y) {
    return objects.slice(0).reverse().find(function(v) {
        return test(v);
    });
}

这样您就不必担心会忘记重新反转阵列。