• [记录] JavaScript 中的数组操作


    数组原型:
    自定义数组原型函数,给所有数组添加公共方法

    Array.prototype.unique = function () {
        var arr = []; // 临时数组 - 存放去重后的数据
        for(var i = 0, len = this.length; i < len; i++){
            // 数组的indexOf有兼容性问题, 未检索到则返回 -1
            if ( arr.indexOf( this[i] ) == -1 ) {
                arr.push( this[i] );
            }
        }
        return arr;
    };
    var codeArr = [3,1,4,1,5,9,2,6,5,5,5,6,9,1,1,1,3];
    console.log( codeArr.unique() );
    // [3, 1, 4, 5, 9, 2, 6]
    


    A. 定义方式;

       var arr = []; // 数组字面量
       var arr = new Array(); // 数组构造函数
    


    B. 数组的读和写

       arr[num]  // 不可以溢出读  结果undefined
       arr[num] = xxx; // 可以溢出写 
    


    改变原数组方法:
    1. arr.push()、arr.pop()

    arr.push() 方法用于在数组的末端添加一个或多个元素,并返回添加新元素后的数组长度。
    var arr = [];
    arr.push(1); // 1
    arr.push("A"); // 2
    arr.push(true, {}); // 4
    console.log( arr ); // ["1", "A", true, {}]
    


    模拟数组方法:

    Array.prototype.push = function (){
        for( var i=0;i<arguments.lenght;i++){
            this[this.length] = arguments[i];
        }
        return this.length;
    } 
    


    arr.pop() 方法用于删除数组的最后一个元素,并返回该元素。

    var arr = ["A", "B", "C"];
    arr.pop(); // "C"
    console.log( arr ); // ["A", "B"]
    
    // 空数组使用 pop() 方法,不会报错,而是返回 undefined
    [].pop(); // undefined
    


    2. arr.shift()、arr.unshift()
    arr.shift() 方法用于删除数组的第一个元素,并返回该元素。

    var arr = ["A", "B", "C"];
    arr.shift(); // "A"
    console.log( arr ); // ["B", "C"]
    


    arr.unshift() 方法用于在数组的第一个位置添加元素,并返回添加新元素后的数组长度。

    var arr = ["A", "B", "C"];
    arr.unshift("H"); // 4
    console.log( arr ); // ["H", "A", "B", "C"]
    // 添加多个
    arr.unshift("Y", "X");
    console.log( arr ); // ["Y", "X", "H", "A", "B", "C"]
    


    3. arr.sort([fn]);
    arr.sort() 方法对数组成员进行排序,默认是按照字典顺序排序。

    ["d", "c", "b", "a"].sort();
    // ["a", "b", "c", "d"]
    
    [6, 5, 4, 3, 2, 1].sort();
    // [1, 2, 3, 4, 5, 6]
    
    [11, 101].sort();
    // [101, 11]
    
    [10111, 1101, 111].sort();
    // [10111, 1101, 111]
    默认排序不是按照大小排序,而是按照字典顺序。
    也就是说,数值会被先转成字符串,再按照字典顺序进行比较,所以 101 排在 11 的前面
    


    sort() 自定义方式排序

    var arr = [10111, 1101, 111];
    arr.sort(function (a, b) {
        // 1. 必须写两个形参,表示进行比较的两个数组成员      
        // 2. 看返回值 
        //    1) 大于 0, 表示第一个排在第二个后面
        //    2) 其他情况, 都是第一个排在第二个前面 
        return a - b;    
    });  
    // [111, 1101, 10111]
    


    数组中的对象数据:

    var arr = [
        { name: "张三", age: 30 },
        { name: "李四", age: 24 },
        { name: "王五", age: 28 }
    ];
    arr.sort(function (a, b) {
        return a.age - b.age;
    });
    // [
    //   { name: "李四", age: 24 },
    //   { name: "王五", age: 28 },
    //   { name: "张三", age: 30 }
    // ]
    


    4. arr.reverse()
    用于颠倒排列数组元素,返回改变后的数组

     
    var arr = ["A", "B", "C"];
    arr.reverse(); 
    // ["C", "B", "A"] 
    


    5. arr.splice(从第几位开始, 截取长度, 切口处添加新数据)
    用于删除原数组的一部分成员,并可以在删除的位置添加新的数组成员,返回值是被删除的元素

    var arr = ["A", "B", "C", "D", "E", "F"];
    // 一个参数时: 删除当前位置后面所有元素
    arr.splice(2); // ["C", "D", "E", "F"]
    // 一个参数时: 负数,表示从倒数位置开始删除
    arr.splice(-3); // ["D", "E", "F"]
    
    // 指定删除长度
    arr.splice(1, 2); // ["E", "F"]
    // 从第一个位置 E 开始删除2个元素
    arr.splice(1, 0); // ["E", "F"]
    // 截取长度为0是,表示不删除
    
    // 从数组的第一个位置添加两个新元素
    arr.splice(1, 0, "A", "B"); // ["E", "A", "B", "F"]
    // 从第一个位置删除2个元素,然后添加新元素
    arr.splice(1, 2, "V", "V", "M"); // ["E","V","V","M","F"]
    


    不改变原数组的方法:
    1. arr.concat()
    用于多个数组合并。将新添加的成员,添加到原数组成员的后面, 然后返回一个新数组

    ['hello'].concat(['world]);
    // ['hello', 'world']
    
    ['hello'].concat(['world'], ['!']);
    // ['hello','world','!']
    
    [].concat({a: 1}, {b: 2});
    // [{a: 1}, {b: 2}]
    
    [2].concat({a: 1});
    // [2, {a: 1}]
    
    [1,2,3].concat(4,5,6);
    // [1, 2, 3, 4, 5, 6]
    


    如果数组成员包括对象, concat 方法返回当前数组的一个浅拷贝。指的是新数组拷贝的是对象的引用。
    注意:改变原对象以后,信数组跟着改变。

    var oldArr = [{ a: 1}];
    var newArr = oldArr.concat();
    oldArr[0].a = 10;
    console.log( newArr[0].a );
    


    2. arr.join()
    指定参数作为分隔符,把数组转成字符串;默认用逗号分隔

    var arr = [1, 2, 3, 4];
    arr.join(' '); // '1, 2, 3, 4'
    arr.join('|'); // '1 | 2 | 3 | 4'
    arr.join(); //'1,2,3,4'
    // 如果数组成员是undefined或null或空位,会被转成空字符串
    [undefined, null].join('#'); // '#'
    ['A', , 'B'].join('-'); // 'a--b'
    


    3. arr.toString() 返回数组的字符串形式

    var arr = [1, 2, 3, 4];
    arr.toString(); // '1,2,3,4'
    
    var arr = [1, 2, 3, [4,5,6]];
    arr.toString(); // '1,2,3,4,5,6'
    


    4. arr.slice(从该位开始截取, 截取到该位);
    用于提取目标数组的一部分,返回一个新数组;

    var arr = ['a','b','c'];
    // 没有参数,返回原数组的拷贝
    arr.slice(); // ['a','b','c']
    // 如果省略第二个参数,则一直返回到数组的最后一个成员
    arr.slice(0); // ['a','b','c']
    arr.slice(1); // ['b','c']
    // 包前不包后, 数组的第一位到第二位(不包含第二位)
    arr.slice(1, 2); // ['b']
    arr.slice(2, 6); // ['c']
    // 支持负数,表示倒数计算的位置
    arr.slice(-2); // ['b','c']
    arr.slice(-2,-1); // ['b']
    // 第一个参数大于等于数组的长度
    // 或 第二个参数小于第一个参数,则返回空数组
    arr.slice(4); // []
    arr.slice(2, 1); // []
    


    slice 方法的一个重要应用,是将类数组的对象转为真正的数组。

    var arr = { 0: 'a', 1: 'b', length: 2 };
    Array.prototype.slice.call(arr);
    // ['a', 'b']
    
    Array.prototype.slice.call(document.querySelectorAll('div'));
    Array.prototype.slice.call(arguments);
    


    #### 类数组
    1. 属性要为索引(数字)属性, 必须有length
    2. 不具有数组所具有的方法
    可以给类数组添加数组方法,如push: Array.prototype.push
    如果添加splice方法则就跟数组长一样了 [1, 2, 3]

    var obj = {
        "0": 'a',
        "1": 'b',
        "2': 'c',
        "length": 3,
        "push": Array.prototype.push,
        "splice": Array.prototype.splice
    }
    
    好处: (类数组push是根据length来替换)
    Array.prototype.push = function (target) {
        obj[obj.length] = target;
        obj.length ++;
    }
    


    数组的其它方法:
    arr.map(); // 不改变原数组
    把数组的所有成员依次传入参数函数,把每次执行的结果组成一个新数组返回。

    var numbers = [1, 2, 3];
    numbers.map(function (n) {
        return n + 1;
    });
    // [2, 3, 4]
    


    函数作为参数调用时, 可以传入三个参数(当前成员, 当前位置, 数组本身)

    [1,2,3].map(function(elem, index, arr) {
        return elem * index;
    });
    // [0, 2, 6]
    


    map 方面可以接受第二个参数,用来绑定回调函数内部的 this 变量

    var arr = ['a','b','c'];
    [1,2].map(function(n) {
        // n 是.map前面数组的每一项, this指向arr数组
        return this[n];
    }, arr);
    // ['b', 'c']
    


    遇到数组空位,跳过空位,不执行回调

    var f = function (n) {
        return 'a';
    }
    [1, undefined, 2].map(f); // ['a', 'a', 'a']
    [1, null, 2].map(f); // ['a', 'a', 'a']
    [1, , 2].map(f); // ['a', , 'a']
    


    arr.forEach(); 数组遍历
    forEach 方法与 map 方法很相似, 对数组所有成员进行遍历。
    forEach 方法没有返回值,值用来操作数据。

    // 第一个参数是函数,有三个参数:(当前值, 当前位置, 数组本身)
    [0, 5, 3].forEach(function(elem, index, arr) {
        console.log('['+index+'] = ' + elem); 
    });
    // [0] = 0
    // [1] = 5
    // [2] = 3
    


    可以接受第二个参数,用来绑定回调函数内部的 this 变量

    var out = [];
    [0, 5, 3].forEach(function(n) {
        this.push(n * n);
    }, out);
    console.log(out); // [0, 25, 9]
    


    注意:
    1. forEach 方法会跳过数组的空位
    2. forEach 方法无法中断循环, 总会将所有成员遍历完。
    arr.filter(); 过滤数组成员
    用于过滤数组成员,满足条件的成员组成一个新数组返回。

    第一个参数是回调函数,必填。遍历所有成员,满足条件的成员组成一个新数组返回。

    [1,2,3,4,5].filter(function(elem) {
        return (elem > 3);
    });
    // [4, 5]
    


    返回数组中所有布尔值为 true 的成员

    [0, 1, 'a', false, null].filter(Boolean);
    // [1, 'a']
    


    回调函数可以接受三个参数: (当前成员,当前位置,数组本身)

    [1,2,3,4,5].filter(function(elem, index, arr) {
        return index % 2 === 0;
    });
    // [1, 3, 5]
    


    接受第二个参数,用来改变回调函数中的 this 变量

    var obj = { Max: 3 };
    var arr = [0, 5, 3, 4, 16];
    arr.filter(function(n) {
        // this 指向 obj
        if(n > this.Max) {
            return true;
        }
    }, obj);
    // [5, 4, 16]
    


    arr.some(fn)、every(fn);
    依次遍历数组成员,回调函数接受三个参数: (当前成员,当前位置,数组本身) 返回一个布尔值.
    可以接受第二个参数,用来改变回调函数中的 this 变量

    some 方法是只要一个满足条件就返回true, 否则返回 false

    var arr = [1, 2, 3, 4, 5];
    arr.some(function (elem, index, arr) {
        return elem >= 3;
    });
    // true;
    


    every 方法是全部满足条件才返回true,否则返回 false

    var arr = [1, 2, 3, 4, 5];
    arr.some(function (elem, index, arr) {
        return elem >= 3;
    });
    // false;
    


    对于空数组, some 方法返回 false , every 方法返回 true, 回调函数不执行

    function isEven(x) {
        return x % 2 === 0;
    }
    [].some(isEven); // false
    [].every(isEven); // true
    


    reduce()、reduceRight() 返回最终的统计结果
    reduce 是从左到右处理(第一个到最后一个)
    reduceRight 是从右到左处理(最后一个到第一个)
    第一个参数是一个回调函数, 接受四个参数
    1. 积累变量, 默认第一个成员 (必须)
    2. 当前变量, 默认第二个成员 (必须)
    3. 当前位置(从0开始)
    4. 原数组

    [1, 2, 3, 4, 5].reduce(function (a, b) {
        console.log(a, b);
        return a + b;
    });
    // 1 2
    // 3 3
    // 6 4
    // 10 5
    //最后结果:15
    


    第二个参数,指定初始值,在初始值的基础上累加

    [1, 2, 3, 4, 5].reduce(function (a, b) {
        console.log(a, b);
        return a + b;
    }, 10);
    // 25
    


    空数组娶不到初始值,reduce方法会报错。

    function add(prev, cur) {
      return prev + cur;
    }
    [].reduce(add);
    // TypeError: Reduce of empty array with no initial value
    [].reduce(add, 1); // 默认返回初始值
    // 1
    


    arr.indexOf(查找元素, 指定位置)、arr.lastIndexOf(查找元素,指定位置) // IE8不兼容, 会报错
    返回给定元素在数组中第一次出现的位置,如果没有找到则返回 -1

    var arr  = ["a", "b", "c"];
    arr.indexOf("b"); // 1
    arr.indexOf("v"); // -1
    // 指定搜索的开始位置
    arr.indexOf("a", 1); // -1
    


    lastIndexOf 方法返回给定元素在数组中最后一次出现的位置,如果没有找到则返回-1

    var a = [2, 5, 9, 2];
    a.lastIndexOf(2) // 3
    a.lastIndexOf(7) // -1
    


  • 相关阅读:
    python闭包&深浅拷贝&垃圾回收&with语句
    Python基本数据类型
    面向对象
    四则运算2
    周总结01
    软件工程个人作业01
    java web中乱码的种类和一些解决方式
    java web 增加信息课堂测试00
    课程00作业
    动手动脑07
  • 原文地址:https://www.cnblogs.com/yuxi2018/p/9456636.html
Copyright © 2020-2023  润新知