HTML

  1. <ul>
  2. <li></li>
  3. <li></li>
  4. <li></li>
  5. <li></li>
  6. <li></li>
  7. <li></li>
  8. <li></li>
  9. </ul>
  10. <div id="data" style="display: none;">
  11. [{"id":"1","course":"前端开发之企业级深度JavaScript特训课【JS++前端】","classes":"19","teacher":"小野","img":"ecmascript.jpg","is_free":"1","datetime":"1540454477","price":"0"},
  12. {"id": "2","course":"WEB前端工程师就业班之深度JSDOM+讲师辅导-第3期【JS++前端】","classes":"22","teacher":"小野","img":"dom.jpg","is_free":"0","datetime":"1540454477","price":"699"},
  13. {"id":"3","course":"前端开发之企业级深度HTML特训课【JS++前端】","classes":"3","teacher":"小野","img":"html.jpg","is_free":"1","datetime":"1540454477","price":"0"},
  14. {"id":"4","course":"前端开发之企业级深度CSS特训课【JS++前端】","classes":"5","teacher":"小野","img":"css.jpg","is_free":"1","datetime":"1540454477","price":"0"},
  15. {"id":"5","course":"前端就业班VueJS+去哪儿网+源码课+讲师辅导-第3期【JS++前端】","classes":"50","teacher":"哈默","img":"vuejs.jpg","is_free":"0","datetime":"1540454477","price":"1280"},
  16. {"id":"6","course":"前端就业班ReactJS+新闻头条实战+讲师辅导-第3期【JS++前端】","classes":"21","teacher":"托尼","img":"reactjs.jpg","is_free":"0","datetime":"1540454477","price":"2180"},
  17. {"id":"7","course":"WEB前端开发工程师就业班-直播/录播+就业辅导-第3期【JS++前端】","classes":"700","teacher":"JS++名师团","img":"jiuyeban.jpg","is_free":"0","datetime":"1540454477","price":"4980"}]
  18. </div>

es3 for数组循坏

    var data = JSON.parse(document.getElementById('data').innerHTML),
        oLi = document.getElementsByTagName('li');

    for (var i = 0; i < data.length; i++) {
        console.log(data[i], i, data);
                            //element index array
        oLi[i].innerHTML = data[i].course;
    }

效果:

image.png

1.forEach

forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。
注意: forEach() 对于空数组是不会执行回调函数的。

    data.forEach(function(elem,index,array){
      oLi[index].innerHTML =  elem.course;
      console.log(this);
    });

重写forEach

    var data = JSON.parse(document.getElementById('data').innerHTML),
        oLi = document.getElementsByTagName('li');

    Array.prototype.myForEach = function (fn) {
        var arr = this,
            len = arr.length,
            arg2 = arguments[1] || window;
        for (var i = 0; i < len; i++) {
            fn.apply(arg2, [arr[i], i, arr]);
        }
    }
    data.myForEach(function(elem,index,array){
        oLi[index].innerHTML = elem.course;
    })

总结:
  foreach适用于只是进行集合或数组遍历,for则在较复杂的循环中效率更高。
  foreach不能对数组或集合进行修改(添加删除操作),如果想要修改就要用for循环。
  所以相比较下来for循环更为灵活。

2.filter

filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。(true/false)
注意: filter() 不会对空数组进行检测。
注意 对filter返回新数组的修改会影响原数组

    var newArr = data.filter(function (elem, index, array) {
        return elem.is_free === '1';
    });

image.png

注意 对filter返回新数组的修改会影响原数组
image.png

重写filter

解决对filter返回新数组的修改会影响原数组的问题

对数组进行深拷贝操作 push进新新数组 避免对新数组的操作影响原数组的数据

    Array.prototype.myFilter = function (fn) {
        var arr = this,
            len = arr.length,
            arg2 = arguments[1] || window,
            nArr = [],
            item; //存储深拷贝的和变量
        for (var i = 0; i < len; i++) {
            // 对数组进行深拷贝操作 避免对新数组的操作影响原数组的数据
            item = tools.deepClone(arr[i]);
            // 如果函数返回值是true 则push进一个新数组
            fn.apply(arg2, [arr[i], i, arr]) ? nArr.push(item) : '';
        }
        // 循环结束返回新数组
        return nArr;
    }

    var newArr = data.myFilter(function (elem, index, array) {
        return elem.is_free === '1';
    })

 //tools.deepClone
 var tools = {
  deepClone: function (origin, target) {
    var target = target || {},
      toStr = Object.prototype.toString,
      arrType = '[object Array]';
    for (var key in origin) {
      if (origin.hasOwnProperty(key)) {
        if (typeof (origin[key]) === 'object' && origin[key] !== null) { // 先测是否是引用型 typeof([]) 等于 object
          target[key] = toStr.call(origin[key]) === arrType ? [] : {};
          deepClone(origin[key], target[key]); //递归执行
        } else {
          target[key] = origin[key];
        }
      }
    }
    return target;
  }
}

3.map

**map()** 方法创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值。

    newArr = data.map(function (elem, index, array) {
        elem.course = this.name + elem.course;
        return elem;

    },{name:'[js++前端]'});

对新数组的所有修改都会影响原数组
image.png

重写map

解决新数组的修改会影响原数组的方案
对数组进行深拷贝操作 避免对新数组的操作影响原数组的数据

    Array.prototype.myMap = function (fn) {
        var arr = this,
            len = arr.length,
            arg2 = arguments[1] || window,
            nArr = [],
            item;

        for (var i = 0; i < len; i++) {
            item = tools.deepClone(arr[i]);
            nArr.push(fn.apply(arg2, [item, i, arr]))
        }
        return nArr;
    }
    var newArr = data.myMap(function (elem, index, array) {
        elem.course = this.name + elem.course;
        return elem;

    }, { name: '[js++前端]' });

 //tools.deepClone
 var tools = {
  deepClone: function (origin, target) {
    var target = target || {},
      toStr = Object.prototype.toString,
      arrType = '[object Array]';
    for (var key in origin) {
      if (origin.hasOwnProperty(key)) {
        if (typeof (origin[key]) === 'object' && origin[key] !== null) { // 先测是否是引用型 typeof([]) 等于 object
          target[key] = toStr.call(origin[key]) === arrType ? [] : {};
          deepClone(origin[key], target[key]); //递归执行
        } else {
          target[key] = origin[key];
        }
      }
    }
    return target;
  }
}

image.png

实战

先筛选符合条件的数据数组 再循坏渲染

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <p id="nav">
        <a href="javascript:;" data-fileId="all">全部课程</a>
        <a href="javascript:;" data-fileId="pay">付费课程</a>
        <a href="javascript:;" data-fileId="free">免费课程</a>
    </p>

    <!-- 列表 -->
    <ul class="list" id="J_list">
    </ul>
    <div id="data" style="display: none;">
        [{"id":"1","course":"前端开发之企业级深度JavaScript特训课【JS++前端】","classes":"19","teacher":"小野","img":"ecmascript.jpg","is_free":"1","datetime":"1540454477","price":"0"},
        {"id":"2","course":"WEB前端工程师就业班之深度JSDOM+讲师辅导-第3期【JS++前端】","classes":"22","teacher":"小野","img":"dom.jpg","is_free":"0","datetime":"1540454477","price":"699"},
        {"id":"3","course":"前端开发之企业级深度HTML特训课【JS++前端】","classes":"3","teacher":"小野","img":"html.jpg","is_free":"1","datetime":"1540454477","price":"0"},
        {"id":"4","course":"前端开发之企业级深度CSS特训课【JS++前端】","classes":"5","teacher":"小野","img":"css.jpg","is_free":"1","datetime":"1540454477","price":"0"},
        {"id":"5","course":"前端就业班VueJS+去哪儿网+源码课+讲师辅导-第3期【JS++前端】","classes":"50","teacher":"哈默","img":"vuejs.jpg","is_free":"0","datetime":"1540454477","price":"1280"},
        {"id":"6","course":"前端就业班ReactJS+新闻头条实战+讲师辅导-第3期【JS++前端】","classes":"21","teacher":"托尼","img":"reactjs.jpg","is_free":"0","datetime":"1540454477","price":"2180"},
        {"id":"7","course":"WEB前端开发工程师就业班-直播/录播+就业辅导-第3期【JS++前端】","classes":"700","teacher":"JS++名师团","img":"jiuyeban.jpg","is_free":"0","datetime":"1540454477","price":"4980"}]
    </div>

    <!-- 模板 -->
    <script type="text/html" id="J_itemTpl">
        <li>{{course}}</li>
    </script>
    <script src="./utils.js"></script>
    <script src="./js/demo.js"></script>
    <script></script>
</body>

</html>
;
(function (document) {
    // 
    var data = JSON.parse(document.getElementById('data').innerHTML),
        oList = document.getElementById('J_list'),
        tpl = document.getElementById('J_itemTpl').innerHTML,
        oNav = document.getElementById('nav');
    // console.log(data, oList, tpl, oNav);

    function init() {
        bindEvent();
        renderList(data);
    }

    function bindEvent() {
        oNav.addEventListener('click', selectCourse, false);
    }

    function selectCourse(e) {
        console.log(e.target);
        var e = e || window.event,
            tar = e.target || e.srcElement,
            tarName = tar.tagName.toLowerCase();
        e.preventDefault ? e.preventDefault() : (e.returnValue = false);
        // console.log(e, tarName);
        if (tarName === 'a') {
            var fileId = tar.getAttribute('data-fileId');
            console.log(fileId);
            // console.log(fileId);
            renderList(filterData(data, fileId));
        }
    }

    // 筛选符合条件的数组
    function filterData(data, fileId) {
        var arr = data.myFilter(function (elem, index, array) {

            switch (fileId) {
                case 'all':
                    return true;
                case 'free':
                    return elem.is_free === '1';
                case 'pay':
                    return elem.is_free === '0';
                default:
                    return true;
            }
        });
        return arr;
    }

    // 渲染里列表
    function renderList(data) {
        var list = '';
        data.forEach(function (elem, index, arr) {
            list += tpl.replace(/{{(.*?)}}/g, function (node, key) {
                return {
                    course: elem.course
                } [key]
            });
        });
        oList.innerHTML = list;
    }
    init();
})(document);