JavaScript中的遍历

304 阅读2分钟

普通的for循环

function fun1() {
    var arr = ['a', 'b', 'c', 'd', 'e'];
    for (let index = 0, len = arr.length; index < len; index++) {
      let element = arr[index];
      
      if (index === 1) { // 演示 continue 
        continue;
      }
      
      if (index === 2) { // 演示 break 
        break;
      }          
      console.log('element: ', element);          
    }

    console.log('fun1:', 'end');
  }

for label

function fun2() {
    var arr = ['a', 'b', 'c', 'd', 'e'];
    tag: // 标签需紧邻循环
    for (let i = 0, len = arr.length; i < len; i++) {
      let element = arr[i];
      
      // if (i === 1) {
      //   continue;
      // }
      
      // if (i === 2) {
      //   break;
      // }
      for (let j = 0, len = arr.length; j < len; j++) {
        let element = arr[j];
        
        if (j === 1) {
          continue tag;
        }
        
        // if (j === 2) {
        //   break tag;
        // }
        
      // 当执行 continue;时跳过当前循环
       // 当执行 break;时跳过当前循环         
        console.log('element for2: ', i);          
      }
      // 当执行continue tag; 时,调至tag处。同时跳过当前所有循环。此语句永远不执行
       // 当执行break tag; 时,调至tag处。同时退出所有循环。此语句永远不执行
      console.log('element for1: ', element);          
    }

    console.log('fun2:', 'end');
  }

forEach

var name = 'win'
  function fun3() { // 不能正常的跳过/跳出循环
    var arr = ['a', 'b', 'c', 'd', 'e'];
    var arrObj = {
      name:'fun3'
    }
    arr.forEach(function(item, index){
      if (index === 1) {
        
        return; // 结束函数  相当于跳出当前循环
      }
      console.log(item, index);
    });
    
    // try { // 终止循环
    //   arr.forEach(function(item, index){
    //     console.log(item)
    //     throw new Error('终止运行'); // 终止运行
    //   }); 
    // } catch(e){
    //   console.log(e.message);
    // }

    // try { // 绑定回调函数的this
    //   arr.forEach(function(item, index){
    //     if(index === 1){
    //       console.log(this.name)
    //     }
    //     console.log(item)
    //   }, arrObj); 
    // } catch(e){
    //   console.log(e.message);
    // }


    console.log('fun3:', 'end');
  }

map、filter、some、every

function fun4() {
    var arr = ['a', 'b', 'c', 'd', 'e'];
    // 原数组保持不变,返回一个新的数组
    var arr1 = arr.map(function(item, index, arr2){
        arr2.push('111111111111')
        // arr === arr2
      console.log(arr2, arr2.length)
      return item + '----------map'
    });
    
    // 过滤通过条件的元素组成一个新数组, 原数组不变
    // var arr1 = arr.filter(function(item, index, arr2){
    //   return index > 3
    // });
    
    // 遍历数组中是否有符合条件的元素,返回Boolean值
    // var arr1 = arr.some(function(item, index, arr2){
    //   return item  === 'a'
    // });

    // 遍历数组中是否每个元素都符合条件, 返回Boolean值
    // var arr1 = arr.every(function(item, index, arr2){
    //   return item === 'a'
    // });

    console.log(arr, arr1)

    console.log('fun4:', 'end');
  }

for in

// for in它不一定根据定义时的顺数输出,所有浏览器的最新版本现在都按chrome执行,先把当中的非负整数键提出来,排序好输出,然后将剩下的定义时的顺序输出。
  // 数组中遍历出来的键名是字符形式的,一般用来遍历对象
  function fun5() {
    var arr = ['a', 'b', 'c', 'd', 'e'];
    var obj = {a:'a', 1: 'b'};
    // for in遍历的是数组的索引(即键名) 一般不用来遍历数组
    for(item in arr){
      console.log(item, arr[item])
    }
    // 遍历对象的键名。
    for(item in obj){
      console.log(item, obj[item])
    }


    console.log('fun5:', 'end');
  }

for of

  // for of   号称是为各种不同的数据结构提供统一的访问机制
  function fun6() {
    var arr = ['a', 'b', 'c', 'd', 'e'];
    // 读取键值
    // for(let v of arr) {
    //   console.log(v); // red green blue
    // }

    for (let index of arr.keys()) { // 遍历key
      console.log('index:', index);
    }


    // for (let elem of arr.values()) {  // 谷歌浏览器暂不支持  同数组的for of
    //   console.log('elem:', elem);
    // }


  for (let [index, elem] of arr.entries()) { // 遍历key和value
    console.log('index, elem:', index, elem);
  }


    console.log('fun6:', 'end');
  }


  // 提供了遍历所有数据结构的统一操作接口。
  // 一种数据结构只要部署了 Iterator 接口,我们就称这种数据结构是“可遍历的”(iterable)。
  // 默认的 Iterator 接口部署在数据结构的Symbol.iterator属性
  // 凡是部署了Symbol.iterator属性的数据结构,就称为部署了遍历器接口。调用这个接口,就会返回一个遍历器对象。
  // 遍历器对象拥有一个next方法。
    // 当有值时,next方法返回 { value: "", done: false }
    // 当没有值的时候next方法返回 { value: undefined, done: true }
    

Iterator 接口 和 遍历器对象

function fun7() {
    var arr = ['a', 'b'];
    let iter = arr[Symbol.iterator](); // 返回遍历器对象

    iter.next() // { value: 'a', done: false }
    iter.next() // { value: 'b', done: false }
    iter.next() // { value: 'c', done: false }
    iter.next() // { value: undefined, done: true }


    console.log('fun7:', 'end');
  }

自定义Iterator 接口

function fun8() {
    if (!Array.prototype.values) {
      getValueIt()
    }
    
    function getValueIt(){
      Array.prototype.values = function(){
          var index = -1,len = this.length;
          var next = {
                      next: () => {
                          
                          if(index !== len - 1){
                              index++
                              return {value:this[index], done: false}
                          } else {
                              return {value:undefined, done: true}
                          }

                      } 
                  };	
        return {
          [Symbol.iterator]: () =>{
                  return next
            }
        }

      }
    }
    
    for(var v of ['a', 'b', 'c'].values()){
        if(v === 'a'){
            continue 
        }
        console.log(v)
    }

    console.log('fun8:', 'end');
  }

类数组 同数组。如果没有的话:1、部署接口,2、转化成数组

// fun9(1,2,3,4,5) // 类数组  同数组。如果没有的话:1、部署接口,2、转化成数组
  function fun9() {
    
    arguments[Symbol.iterator] = null
    
    // arguments[Symbol.iterator] = Array.prototype[Symbol.iterator]
    
    for (var iterator of Array.from(arguments)) {
      console.log(iterator)
    }
    console.log('fun9:', 'end');
  }

对象

function fun10() {
    
    // var obj = {a:1, 1:'b', c:2};        
    // for (var iterator of Object.keys(obj)) {
    //   console.log(iterator)
    // }

    var obj = {
      '0':1,
      '1':'b',
      '2':2,
      splice:Array.prototype.splice,
      [Symbol.iterator] : Array.prototype[Symbol.iterator],
      length:3
    };
    console.log(obj, arguments)        
    for (var iterator of obj) {
      console.log(iterator)
    }

    console.log('fun10:', 'end');
  }
  
  // 已经部署了iterator接口的对象
  // 数组、Set 和 Map 结构、某些类似数组的对象(比如arguments对象、DOM NodeList 对象)、Generator 对象,以及字符串。