引物/库循环函数仅执行一次

时间:2018-06-17 13:37:14

标签: javascript html loops foreach

我经历了所有的环状火灾只有一次'问题,但无法找到问题的解决方案。

我正在开发一个需要大量循环函数的项目,其中元素作为主题。我以为我会创建一个库函数(我认为'引用函数'是一个更好的术语),我可以稍后调用,每次只需要一行代码。所以我尝试过,但它的表现并不像我预期的那样,因为它只会触发一次。这是我的实验代码:



<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
</head>
<body>
    <span class="demo">See me.</span>
    <span class="demo">See me.</span>
    <span class="demo">See me.</span>
    <span class="demo">See me.</span>
    <script>
        var forAll = function(elems) {
            for (var i=0, n=elems.length; i<n; i++) {
                console.log('The elems[i] == ' + elems[i]);
                return elems[i];
            }
        }
        var demos = document.querySelectorAll('.demo');
        forAll(demos).style.color = 'red';
        console.log('The forAll(demos) ==' + forAll(demos));
    </script>
</body>
</html>
&#13;
&#13;
&#13;

从结果和控制台可以看到引发函数只触发一次。我究竟做错了什么?我完全自学了Javascript,所以如果我缺少基本的东西,请放轻松。

添加:在这种情况下,IE11是一个使用频繁的浏览器,因此forEach不是一个选项。

3 个答案:

答案 0 :(得分:3)

此函数中的for循环将只迭代一次:

var forAll = function(elems) {
        for (var i=0, n=elems.length; i<n; i++) {
            console.log('The elems[i] == ' + elems[i]);
            return elems[i];
        }
    }

返回停止for循环并返回函数的执行。

修改:这是一个代码片段,可能会按照@AndroidNoobie

的建议执行您所期望的操作

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
</head>
<body>
    <span class="demo">See me.</span>
    <span class="demo">See me.</span>
    <span class="demo">See me.</span>
    <span class="demo">See me.</span>
    <script>
        var forAll = function(elems) {
            for (var i=0, n=elems.length; i<n; i++) {
                elems[i].style.color = 'red';
            }
            
            return elems;
        }
        var demos = document.querySelectorAll('.demo');           
        console.log('The forAll(demos) ==' + forAll(demos));
    </script>
</body>
</html>

答案 1 :(得分:2)

我认为您的实际问题是“如何在不支持forEach的浏览器中实施forEach - 类似行为?”

在这种情况下,你可以这样做:

if (!Array.prototype.forEach) {
    Array.prototype.forEach = function(fn, scope) {
        for(var i = 0, len = this.length; i < len; ++i) {
            fn.call(scope, this[i], i, this);
        }
    }
}

然后你可以在你的数组上调用forEach(尽管一般来说,修改像数组这样的内置对象的原型并不是一个好主意。)

但是你问的问题(为什么循环只迭代一次)已经被@facundo和@Pointy回答了。

修改:添加了代码段。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
</head>
<body>
    <span class="demo">See me.</span>
    <span class="demo">See me.</span>
    <span class="demo">See me.</span>
    <span class="demo">See me.</span>
    <script>
    
        if (!Array.prototype.forEach) {
          Array.prototype.forEach = function(fn, scope) {
              for(var i = 0, len = this.length; i < len; ++i) {
                  fn.call(scope, this[i], i, this);
              }
          }
        }
        var demos = document.querySelectorAll('.demo');
        demos.forEach(function(item){
            item.style.color = 'red';
        })
        console.log('The forAll(demos) ==' + demos);
    </script>
</body>
</html>

答案 2 :(得分:0)

最终,使用NodeLists使Internet Explorer(IE)支持forEach变得非常容易。通过http://tips.tutorialhorizon.com/2017/01/06/object-doesnt-support-property-or-method-foreach/上的微小填充物:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
</head>
<body>
    <span class="demo">See me.</span>
    <span class="demo">See me.</span>
    <span class="demo">See me.</span>
    <span class="demo">See me.</span>
    <script>
        // Polyfill to make IE9+ support forEach w/ NodeLists:
        (function () {
            if (typeof NodeList.prototype.forEach === "function")
                return false;
            else 
                NodeList.prototype.forEach = Array.prototype.forEach;
        })();

        // Works with NodeLists (i.e. HTMLcollections):
        var demos = document.querySelectorAll('.demo');
        demos.forEach(function(item) {
                item.style.color = 'red';
        })

        // As well as with Arrays:
        var gurkins = ['gur1', 'gur2', 'gur3'];
        gurkins.forEach(function(item) {
            console.log(item);
        });
    </script>
</body>
</html>

在IE11中测试,并且根据其模拟功能,它也可以在10和9中工作(不是8)。

感谢您的时间和精力,facundo和AndroidNoobie,但您可能会明白这是最好的解决方案。