美文网首页
Javascript常用的数组方法

Javascript常用的数组方法

作者: 顽皮的雪狐七七 | 来源:发表于2017-05-20 21:38 被阅读822次

    Javascript有很多数组的方法,有的人有W3C的API,还可以去MDN上去找,但是我觉得API上说的不全,MDN上又太多。。其实常用的就那几个,很多都可以用那几个方法解出来。

    很多方法中有兼容性的,在使用的时候,把兼容代码复制粘贴即可。

    先贴上来数组和字符串的方法的比较,我在学习的时候也是会混。所以做了小总结。之后就是数组方法和一些实例。如果有侧边栏就好了,看得就比较清楚。

    数组 字符串

    slice | slice substring 截取需要开始和结束index的

    splice | substr 截取需要开始index和截取长度的

    concat | concat 都是连接,一个是连接数组,一个是连接字符串

    indexOf | indexOf 搜索元素在不在里面,返回index值或者-1

    join | split 这就是两个反义词啊,相互转化的利器

    • 截取方法中,字符串有三种方法slice / substring / substr ,数组方法有两个slice / splice
      其中字符串的slice 和 substring 是要开始和结束的索引,substr 是要开始索引和长度
      数组的slice是要开始和结束索引,但是splice是要开始索引和长度
    • 搜索元素方法中,数组和字符串都有indexOf方法,但是字符串多出来两种方法charAt和charCodeAt
      其中indexOf是返回索引,charAt是返回索引对应的值,charCodeAt是返回对应值的ASCII码值。
    • 数组的遍历有4中方法,map,every,foreach,some,filter
      其中foreach开始就停不下来,全部遍历。every遍历一个就判断一下,true就继续遍历下一个,false就跳出。map就是边遍历边运算。some返回的是布尔值,符合就是true,不符合就是false。filter返回的是符合元素组成的数组。
    • 增加数组元素,前面unshift,后面push
      移除数组元素,前面shift,后面pop
    • 数组和字符串都有concat方法,各自连接各自的,是数组就连接到数组,字符串就连接成字符串
    • 比较重要的两个就是数组和字符串之间的转化的两个方法
      join是数组转字符串,split是字符串转数组

    数组

    Array.prototype

    Array.prototype 属性表示构造函数的原型,并允许您向所有Array对象添加新的属性和方法。

    /*
    如果JavaScript本身不提供 first() 方法,
    添加一个返回数组的第一个元素的新方法。
    */ 
    
    if(!Array.prototype.first) {
        Array.prototype.first = function() {
            return this[0];
        }
    }
    

    Array.prototype本身也是一个 Array

    Array.isArray(Array.prototype); 
    // true
    
    //属性
    Array.prototype.constructor
    //所有的数组实例都继承了这个属性,它的值就是 Array,表明了所有的数组都是由 Array 构造出来的。
    Array.prototype.length
    //上面说了,因为 Array.prototype 也是个数组,所以它也有 length 属性,这个值为 0,因为它是个空数组。
    

    判断是不是数组的方式

    Array.isArray( );

    Array.isArray( obj );

    • 静态方法,是数组构造函数的方法

    • obj是需要检测的值,如果是数组,返回true,否则返回false

      // 下面的函数调用都返回 true
      Array.isArray([]);
      Array.isArray([1]);
      Array.isArray(new Array());
      // 鲜为人知的事实:其实 Array.prototype 也是一个数组。
      Array.isArray(Array.prototype); 
      
      // 下面的函数调用都返回 false
      Array.isArray();
      Array.isArray({});
      Array.isArray(null);
      Array.isArray(undefined);
      Array.isArray(17);
      Array.isArray('Array');
      Array.isArray(true);
      Array.isArray(false);
      Array.isArray({ __proto__: Array.prototype });
      
    • 存在兼容问题(IE8及以下不支持)

      //Polyfill
      //假如不存在 Array.isArray(),则在其他代码之前运行下面的代码将创建该方法。
      if (!Array.isArray) {
        Array.isArray = function(arg) {
          return Object.prototype.toString.call(arg) === '[object Array]';
        };
      }
      

    (Object.prototype)toString.call(arr) -> [object Array]

    Object.prototype.toString.call([]) -> [ object Array]

    • 转化成字符串是"[object Array]",可以作为判断条件。
    • Object.prototype.toString.call(obj).slice(8,-1); -> ==='Array'
    • ({}).toString.call(function(){}).slice(8,-1); -> ==='Function'
    • slice截取,前面的是从第八个开始,截取到倒数的第二个。

    instanceof

    对象 instanceof 数据类型

    • console.log(obj instanceof Array);

    • (不严谨)多个页面进行判断,会有问题

      //iframe
        /*B页面嵌套到A页面中,每个页面都有一个top属性,top属性一直都指向A页面的window,所以在A页面定义的函数fn,暴露在B页面的全局环境中,在B页面中也可以调用。*/
        top.fn(); //(就是调用页面A的fn函数)
      
      //那么问题来了:
      B页面:  top.fn([]);
      A页面:  function fn(arr){
                console.log(arr instanceof Array);
                }  //此时会成为false
      
      //要直接访问A页面,访问B页面会报错,因为只打开的页面的top指向自己的window,此时调用了没有定义的函数。
      //防止被嵌套:if( top != window){
            top.location.href = ‘inner-B.html’;} //跳转到自己的地址
      

    数组长度

    • 数组的length属性总是比数组中定义的最后一个元素的下标大一,表示数组中元素的个数。

    • 数组的length属性在创建数组的时候初始化,在添加新元素的时候数组长度改变

      //如果函数中没有参数,a为空数组
      var a = new Array();   // a.length 被初始化为 0
      
      //如果函数参数是一个,参数表示函数的长度
      var b = new Array(10); // b.length 被初始化为 10
      
      //如果函数参数是两个及以上,参数表示数组内容
      var c = new Array("one", "two", "three");  // c.length 被初始化为 3
      c[3] = "four";        // c.length 被更新为 4
      c[10] = "blastoff";   // c.length 变为 11 
      
    • 设置属性length的值可以改变数组的大小,设置值小则被从后截断,设置值大则剩下的值都为undefined

      var a = new Array("one", "two", "three");
      a.length = 2;  //["one", "two"]
      a.length = 5;  //["one", "two", undefined × 3]
      

    遍历数组

    map

    var new_array = array.map (function(value,index,array){ },thisArg);

    • 遍历数组,能够将数组转化为一个新的数组,新数组的值由map方法回调函数的返回值决定。

    • 回调函数的第一个参数是数组的值,第二个参数是索引,第三个参数是被调用的数组。thisArg可选,执行 callback函数时 使用的this值。

    • 如果 thisArg 参数有值,则每次 callback 函数被调用的时候,this都会指向thisArg参数上的这个对象。如果省略了 thisArg参数,或者赋值为null或undefined,则 this 指向全局对象 。

    • 返回值是新的数组

     var arrNew = arr.map(function(value,index){
         console.log(‘索引是’+index+”,内容是:”+value+);
       })
          
     let numbers = [1, 5, 10, 15];
     let roots = numbers.map(function(x) {
          return x * 2;
       });
    // roots is now [2, 10, 20, 30]
    // numbers is still [1, 5, 10, 15]
    
    • 求数组中每个元素的平方根

      var numbers = [1, 4, 9];
      var roots = numbers.map(Math.sqrt);
      /* roots的值为[1, 2, 3], numbers的值仍为[1, 4, 9] */
      
    • 使用 map 重新格式化数组中的对象

      var kvArray = [{key:1, value:10}, 
                     {key:2, value:20}, 
                     {key:3, value: 30}];
      var reformattedArray = kvArray.map(function(obj){ 
        //obj指的是每一个数组元素,是一个对象
         var rObj = {};
         rObj[obj.key] = obj.value;
         return rObj;
      });
      // reformattedArray is now [{1:10}, {2:20}, {3:30}], 
      // kvArray is still [{key:1, value:10}, {key:2, value:20}, {key:3, value: 30}]
      
    • 将数组中的单词转换成对应的复数形式

      var words = ["foot", "goose", "moose", "kangaroo"];
      //定义函数
      function fuzzyPlural(single) {
        //所有的o变成e
        var result = single.replace(/o/g, 'e');  
        if( single === 'kangaroo'){
          result += 'se';
        }
        return result; 
      }
      //遍历每一个元素
      console.log(words.map(fuzzyPlural));
      // ["feet", "geese", "meese", "kangareese"]
      
    • 如何让一个string使用map方法获取字符串中每个字符所对应的ASCII码组成的数组

      var map = Array.prototype.map
      var a = map.call("Hello World", function(x) { 
        return x.charCodeAt(0); 
      })
      // a的值为[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]
      
    • 如何遍历querySelectorAll得到动态对象集合

      var elems = document.querySelectorAll('select option:checked');
      var values = Array.prototype.map.call(elems, function(obj) {
        return obj.value;
      });
      
    • 反转字符串

      var str = '12345';
      Array.prototype.map.call(str, function(x) {
        return x;
      }).reverse().join(''); 
      
      // Output: '54321'
      
    • parseInt等有多个参数的函数要注意

      var a = ['1','2','3'];
      var b = a.map(function(x){
        return parseInt(x);
       }); //[1,2,3]
      
       // 下面的语句返回什么呢:
        ["1", "2", "3"].map(parseInt);
        // 你可能觉的会是[1, 2, 3]
        // 但实际的结果是 [1, NaN, NaN]
      
        //parseInt有两个参数,第二个数是进制数
        //所以以上函数主要执行的是
        var a  = ['1','2','3'];
        var b = a.map(function(ele,index,array){
          return parseInt(ele,index);
          //第三个参数parseInt会忽视, 但第二个参数不会
          // parseInt把传过来的索引值当成进制数来使用
          //而第二个参数假如经过 Number 函数转换后为 0 或 NaN,则将会忽略
          //parseInt(1,0);       1
          //parseInt(2,1);       NaN
          //parseInt(3,2);       NaN
        })
      
        //解决如下
        function returnInt(element){
          return parseInt(element,10);
        }
        ["1", "2", "3"].map(returnInt);
        // 返回[1,2,3]
      
    • 兼容问题 IE8及以下不支持

      // 实现 ECMA-262, Edition 5, 15.4.4.19
      // 参考: http://es5.github.com/#x15.4.4.19
      // 兼容代码
      if (!Array.prototype.map) {
        Array.prototype.map = function(callback, thisArg) {
      
          var T, A, k;
          if (this == null) {
            throw new TypeError(" this is null or not defined");
          }
          // 1. 将O赋值为调用map方法的数组.
          var O = Object(this);
          // 2.将len赋值为数组O的长度.
          var len = O.length >>> 0;
          // 3.如果callback不是函数,则抛出TypeError异常.
          if (Object.prototype.toString.call(callback) != "[object Function]") {
            throw new TypeError(callback + " is not a function");
          }
          // 4. 如果参数thisArg有值,则将T赋值为thisArg;否则T为undefined.
          if (thisArg) {
            T = thisArg;
          }
          // 5. 创建新数组A,长度为原数组O长度len
          A = new Array(len);
          // 6. 将k赋值为0
          k = 0;
          // 7. 当 k < len 时,执行循环.
          while(k < len) {
            var kValue, mappedValue;
            //遍历O,k为原数组索引
            if (k in O) {
              //kValue为索引k对应的值.
              kValue = O[ k ];
              // 执行callback,this指向T,参数有三个.分别是kValue:值,k:索引,O:原数组.
              mappedValue = callback.call(T, kValue, k, O);
              // 返回值添加到新数组A中.
              A[ k ] = mappedValue;
            }
            // k自增1
            k++;
          }
          // 8. 返回新数组A
          return A;
        };      
      }
      

    forEach

    array.forEach(function(value,index,array){},thisArg);

    • 遍历数组,跑起来就停不下来,调用就会遍历整个数组,无法中断循环

    • 回调函数的第一个参数表示数组中的每一个元素,第二个表示索引号,第三个表示正在操作的数组,可选

    • 返回值undefined

      //实例
      function logArrayElements(element, index, array) {
          console.log("a[" + index + "] = " + element);
      }
      
      // 注意索引2被跳过了,因为在数组的这个位置没有项
      [2, 5, ,9].forEach(logArrayElements);
      // a[0] = 2
      // a[1] = 5
      // a[3] = 9
      
      [2, 5,"" ,9].forEach(logArrayElements);
      // a[0] = 2
      // a[1] = 5
      // a[2] = 
      // a[3] = 9
      
    • 使用thisArg

      因为thisArg参数(this)传给了forEach(),每次调用时,它都被传给callback函数,作为它的this值。但是在ES6的箭头函数表达式传入函数参数,thisArg参数会被忽略,因为箭头函数在词法上绑定了this值。

      function Counter() {
          this.sum = 0;
          this.count = 0;
      }
      
      Counter.prototype.add = function(array) {
          array.forEach(function(entry) {
              this.sum += entry;
              ++this.count;
          }, this);
          //console.log(this);
      };
      
      var obj = new Counter();
      obj.add([1, 3, 5, 7]);
      obj.count; 
      // 4 === (1+1+1+1)
      obj.sum;
      // 16 === (1+3+5+7)
      
    • 兼容问题 IE8及以下不支持

      // Production steps of ECMA-262, Edition 5, 15.4.4.18
      // Reference: http://es5.github.io/#x15.4.4.18
      if (!Array.prototype.forEach){
        Array.prototype.forEach = function(callback, thisArg) {
         
          var T, k;
          if (this == null) {
            throw new TypeError(' this is null or not defined');
          }
          // 1. Let O be the result of calling toObject() passing the
          // |this| value as the argument.
          var O = Object(this);
          // 2. Let lenValue be the result of calling the Get() internal
          // method of O with the argument "length".
          // 3. Let len be toUint32(lenValue).
          var len = O.length >>> 0;
          // 4. If isCallable(callback) is false, throw a TypeError exception. 
          // See: http://es5.github.com/#x9.11
          if (typeof callback !== "function") {
            throw new TypeError(callback + ' is not a function');
          }
          // 5. If thisArg was supplied, let T be thisArg; else let
          // T be undefined.
          if (arguments.length > 1) {
            T = thisArg;
          }
          // 6. Let k be 0
          k = 0;
          // 7. Repeat, while k < len
          while (k < len) {
            var kValue;
            // a. Let Pk be ToString(k).
            //    This is implicit for LHS operands of the in operator
            // b. Let kPresent be the result of calling the HasProperty
            //    internal method of O with argument Pk.
            //    This step can be combined with c
            // c. If kPresent is true, then
            if (k in O) {
              // i. Let kValue be the result of calling the Get internal
              // method of O with argument Pk.
              kValue = O[k];
              // ii. Call the Call internal method of callback with T as
              // the this value and argument list containing kValue, k, and O.
              callback.call(T, kValue, k, O);
            }
            // d. Increase k by 1.
            k++;
          }
          // 8. return undefined
        };
      }
      

    every

    array.every(function(value,index){});

    • 根据当前回调函数的返回值决定是否进行下一次循环

      • 如果没有return true,则只是执行一次
      • 回调函数的返回值为true,继续循环
      • 返回值是false,停止循环
    • 第一个参数是数组中的每一个元素 第二个参数表示索引号

    • 兼容问题 IE8及以下不支持

      //兼容问题
      if (!Array.prototype.every){
        Array.prototype.every = function(fun /*, thisArg */){
          'use strict';
      
          if (this === void 0 || this === null)
            throw new TypeError();
      
          var t = Object(this);
          var len = t.length >>> 0;
          if (typeof fun !== 'function')
              throw new TypeError();
      
          var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
          for (var i = 0; i < len; i++){
            if (i in t && !fun.call(thisArg, t[i], i, t))
              return false;
          }
          return true;
        };
      }
      

    some(返回布尔)

    array.some(callback[,thisArg])

    • callback 被调用时传入三个参数:元素的值,元素的索引,被遍历的数组

    • thisArg参数,将会把它传给被调用的callback,作为this 值。否则,在非严格模式下将会是全局对象,严格模式下是undefined

    • 数组中如果有一个满足条件,返回true,否则返回false

      //callback
      function isBigEnough(element, index, array){
        return (element >= 10);
      }
      var passed = [2, 5, 8, 1, 4].some(isBigEnough);
      // passed is false
      passed = [12, 5, 8, 1, 4].some(isBigEnough);
      // passed is true
      
    • some有兼容问题,IE8及以下不支持

      //兼容代码
      if (!Array.prototype.some){
        Array.prototype.some = function(fun /*, thisArg */){
          'use strict';
          if (this === void 0 || this === null)
             throw new TypeError();
          
          var t = Object(this);
          var len = t.length >>> 0;
          if (typeof fun !== 'function')
            throw new TypeError();
      
          var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
          for (var i = 0; i < len; i++){
            if (i in t && fun.call(thisArg, t[i], i, t))
              return true;
          }
          return false;
        };
      }
      

    filter

    var new_array = arr.filter(callback[, thisArg])

    • 判断数组中的每一项是否都满足条件,所有满足条件的则返回新数组

    • callback 用来测试数组的每个元素的函数。调用时使用参数 (element, index, array)
      返回true表示保留该元素(通过测试),false则不保留

    • thisArg 可选,执行callback时的用于this的值

    • 这些概念去看some

      function isBigEnough(element) {
        return element >= 10;
      }
      var filtered = [12, 5, 8, 130, 44].filter(isBigEnough);
      // filtered is [12, 130, 44]
      
      //另一种写法
      var arr = [12, 5, 8, 130, 44];
      var filt = arr.filter(function(element){
        return element >= 10;
      })//filt is [12, 130, 44]
      
    • filter有兼容问题,IE8及以下不支持

      //兼容代码
      //假定 fn.call 等价于 Function.prototype.call 的初始值,且 Array.prototype.push 拥有它的初始值。
      if (!Array.prototype.filter)
      {
        Array.prototype.filter = function(fun /*, thisArg */)
        {
          "use strict";
      
          if (this === void 0 || this === null)
            throw new TypeError();
      
          var t = Object(this);
          var len = t.length >>> 0;
          if (typeof fun !== "function")
            throw new TypeError();
      
          var res = [];
          var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
          for (var i = 0; i < len; i++)
          {
            if (i in t)
            {
              var val = t[i];
      
              // NOTE: Technically this should Object.defineProperty at
              //       the next index, as push can be affected by
              //       properties on Object.prototype and Array.prototype.
              //       But that method's new, and collisions should be
              //       rare, so use the more-compatible alternative.
              if (fun.call(thisArg, val, i, t))
                res.push(val);
            }
          }
      
          return res;
        };
      }
      

    截取数组

    slice(索引)

    array.slice(start,end)

    • start

      • 正数,数组片段开始截取的下标
      • 负数,从数组尾部开始算起,-1是最后一个,-2是倒数第二个
      • 截取一个生成新数组,不影响原来数组,参数开始从0开始,从-1结束
    • end

      • 结束的后一个元素的数组下标
      • 没有指定参数,则默认是到数组结束
      • 如果是负数,就是从末尾开始算起
    • 截取一个生成新数组,不影响原来数组,包含从start到end(不包括该元素)指定的array元素

      var a = [1,2,3,4,5];
      a.slice(0,3);    // 返回 [1,2,3]
      a.slice(3);      // 返回 [4,5]
      a.slice(1,-1);   // 返回 [2,3,4]
      a.slice(-3,-2);  // 返回 [3]; 
      //IE 4存在的Bug: 返回[1,2,3]
      

    splice(长度,可替换)

    array.splice(start, deleteCount, value, ...)

    • 参数有start,deleteCount,options(替换)

      • start开始插入和(或)删除的数组元素的下标
      • deleteCount 从start开始(包括start)要删除的元素个数。参数可选,如果没有指定,就默认到结尾的所有元素
      • value,... 要插入的数组值,从start所指的下标处开始插入
    • 返回值是截取到的数组

      //定义一个数组
      var arr = [10,20,30,40,50,60,70,80,90];
      //三个参数的情况  从索引为三的地方数三个,替换这三个数
      var result = arr.splice(3,3,100,200,300);
      //arr = [10,20,30,100,200,300,70,80,90];
      //result = [40,50,60];
      //两个参数的情况  从索引为三的地方截取三个
      var result1 = arr.splice(3,3);
      //arr = [10,20,30,70,80,90];
      //result = [100,200,300];
      //一个参数的情况,是从索引为三的地方一直到最后截取
      var result2 = arr.splice(3);
      //arr = [70,80,90]
      //result2 = [10,20,30]
      

    连接数组

    join(字符串)

    var string = array.join()

    • 如果没有参数,默认用逗号作为分割符

    • 如果有参数,则参数是用于分隔数组元素的字符或字符串

    • 返回字符串,通过把array每个元素转换成字符串,用参数连接起来

    • 可以用String对象的split()方法进行相反的操作,把字符串根据参数分隔成数组

      var a = new Array(1, 2, 3, "testing");
      //a = [1,2,3,testing]
      var s = a.join("+");  // s 是字符串"1+2+3+testing"
      

    concat

    var new_array = array1.concat('array2','array3')

    • 参数至少是一个

    • 返回一个新数组

    • 如果操作的参数是一个数组,那么添加的是数组中的元素,而不是数组

      var a = [1,2,3];
      a.concat(4, 5)          //返回 [1,2,3,4,5]
      a.concat([4,5]);        //返回 [1,2,3,4,5]
      a.concat([4,5],[6,7])   //返回 [1,2,3,4,5,6,7]
      a.concat(4, [5,[6,7]])  //返回 [1,2,3,4,5,[6,7]]
      

    添加元素

    push

    array.push(value,...)

    • 要添加到array的末尾,可以是一个也可以是多个

    • 返回值是添加后的数组的长度

    • pop()方法和push()方法可以提供先进后出的栈的功能

    • 在对象中添加元素

      var obj = {
          length: 0,
          addElem: function addElem(elem){
              [].push.call(this, elem);
          }
      };
      obj.addElem({});
      obj.addElem({});
      console.log(obj.length);
      // → 2
      

    unshift

    array.unshift(value, ...)

    • 参数是要添加到头部的一个或多个值
    • 返回数组的新长度

    移除元素

    pop

    array.pop()

    • 删除的是数组中的最后一个元素,数组长度-1
    • 返回值是删除的元素
    • 如果数组为空,则数组长度不变,返回undefined
    • pop()方法和push()方法可以提供先进后出的栈的功能

    shift

    array.shift()

    • 移除的是数组中的第一个元素,其余的向前移

    • 返回的是移除元素的值

    • 如果是空数组,则不进行任何操作,返回undefined

    数组排序

    sort

    arr.sort(compareFunction)

    • compareFunction 可选。是用来指定按什么顺序进行排序的函数,可选

    • 返回排序后的数组

    • 如果不传参数,将按照字母(字符编码)顺序最数组进行排序,所以要把数组中的元素转化为字符串以便进行比较

    • 如过按照别的顺序进行排序,就要提供比较函数(参数a,b)

      • a < b 排序后a在b之前,就返回一个小于0的值
      • a = b 返回0
      • a > b 排序后a在b之后,返回一个大于0的值
      // 按照数字顺序排序的排序函数
      //a-b 表示升序排列
      function  sortAscending(a, b) { return a - b; }
      //b-a 表示降序排列
      function  sortDescending(a,b) { return b - a; }
      
      var a = new Array(33, 4, 1111, 222);
      // 按照字母顺序的排序
      a.sort();             // 结果为: 1111, 222, 33, 4
      // 按照数字顺序的排序
      a.sort(sortAscending);  //结果为: 4, 33, 222, 1111
      a.sort(sortDescending); //结果为:1111,222,33,4
      

    reverse

    array.reverse( )

    • 颠倒数组中元素的顺序,不创建新数组

      var a = new Array(1, 2, 3); 
      // a = [1,2,3]    a[0] == 1, a[2] == 3;
      a.reverse(  );             
      //Now  a = [3,2,1]  a[0] == 3, a[2] == 1;
      

    查找数组

    indexOf(返回索引)

    arr.indexOf(searchElement)

    arr.indexOf(searchElement[, fromIndex = 0])

    • searchElement 要查找的元素

    • fromIndex 开始查找的位置

      • fromIndex >= length,意味着不会在数组里查找,返回-1
      • 负值,-1从最后一个开始查找,-2从倒数第二个开始找
    • 返回值如果找到了元素就返回元素在数组中的索引位置,若没有找到则返回-1

      var array = [2, 5, 9];
      array.indexOf(2);     // 0
      array.indexOf(7);     // -1
      array.indexOf(9, 2);  // 2
      array.indexOf(2, -1); // -1
      array.indexOf(2, -3); // 0
      
    • 找出指定元素出现的所有位置

      var indices = [];
      var array = ['a', 'b', 'a', 'c', 'a', 'd'];
      var element = 'a';
      //判断元素在不在数组里面
      var idx = array.indexOf(element);
      //如果元素在数组里面,就循环
      while (idx != -1) {
        //把索引推入新数组中
        indices.push(idx);
        //从找到元素的下一个索引开始继续查找
        idx = array.indexOf(element, idx + 1);
      }
      console.log(indices);
      // [0, 2, 4]
      
    • 判断一个元素是否在数组里,不在则更新数组

      //定义一个函数
      function update(vegs, veg) {
        //如果数组中不存在
          if (vegs.indexOf(veg) === -1) {
            //在数组中添加元素
              vegs.push(veg);
            console.log('New vegs is :' + vegs);
            //如果在数组中存在
          } else if (vegs.indexOf(veg) > -1) {
            //这个元素已经存在在数组中
              console.log(veg + ' already exists in the vegs.');
          }
      }
      
      var vegs = ['potato', 'tomato', 'chillies', 'green-pepper'];
       update(vegs, 'spinach'); 
        // New vegs is : potato,tomato,chillies,green-papper,spinach
       update(vegs, 'spinach');
        // spinach already exists in the vegs.
      
      
    • 兼容问题 IE8及以下不兼容

        //兼容代码
        // Production steps of ECMA-262, Edition 5, 15.4.4.14
        // Reference: http://es5.github.io/#x15.4.4.14
        if (!Array.prototype.indexOf) {
          Array.prototype.indexOf = function(searchElement, fromIndex) {
      
            var k;
            // 1. Let O be the result of calling ToObject passing
            //    the this value as the argument.
            if (this == null) {
              throw new TypeError('"this" is null or not defined');
            }
            var O = Object(this);
            // 2. Let lenValue be the result of calling the Get
            //    internal method of O with the argument "length".
            // 3. Let len be ToUint32(lenValue).
            var len = O.length >>> 0;
            // 4. If len is 0, return -1.
            if (len === 0) {
              return -1;
            }
            // 5. If argument fromIndex was passed let n be
            //    ToInteger(fromIndex); else let n be 0.
            var n = +fromIndex || 0;
            if (Math.abs(n) === Infinity) {
              n = 0;
            }
            // 6. If n >= len, return -1.
            if (n >= len) {
              return -1;
            }
            // 7. If n >= 0, then Let k be n.
            // 8. Else, n<0, Let k be len - abs(n).
            //    If k is less than 0, then let k be 0.
            k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
            // 9. Repeat, while k < len
            while (k < len) {
              // a. Let Pk be ToString(k).
              //   This is implicit for LHS operands of the in operator
              // b. Let kPresent be the result of calling the
              //    HasProperty internal method of O with argument Pk.
              //   This step can be combined with c
              // c. If kPresent is true, then
              //    i.  Let elementK be the result of calling the Get
              //        internal method of O with the argument ToString(k).
              //   ii.  Let same be the result of applying the
              //        Strict Equality Comparison Algorithm to
              //        searchElement and elementK.
              //  iii.  If same is true, return k.
              if (k in O && O[k] === searchElement) {
                return k;
              }
              k++;
            }
            return -1;
          };
        }
      

    ©copyright burning.

    相关文章

      网友评论

          本文标题:Javascript常用的数组方法

          本文链接:https://www.haomeiwen.com/subject/qggyxxtx.html