数组api、数组并集、交集差集、对象合并、深拷贝和浅拷贝都在这了

487 阅读4分钟

一、数组api

const a = [1, 2, 3];b = [2, 4, 5]

// 数组转字符串
console.log(a.toString()); // 1,2,3

// 数组变字符串, 用指定字符分割数组成一个字符串
console.log(a.join('/'));// 1/2/3

// 字符串变数组
const string = '1234'
console.log(string.split()); // ['1234']

// 查找元素首次出现在数组中的位置,若找不到返回-1
console.log(a.indexOf(1)); // 0
console.log(a.indexOf(66)); // -1

// 判断数组中是否包含某个值,返回布尔值
console.log(a.includes(2)); // true
console.log(a.includes(66)); // false

// 数组拼接
console.log(a.concat(b)); //[1, 2, 3, 2, 4, 5]
console.log(a); // [1, 2, 3]

// 反转数组
console.log(a.reverse()); // [3, 2, 1]

// 数组排序,默认升序
console.log(a.sort()); // [1, 2, 3]
console.log(a.sort(function(a,b){ return b-a })); // [3, 2, 1] 
console.log(a.sort(function(a,b){ return a-b })); // [1, 2, 3]

// 选取指定的数组元素
console.log(a.slice(0,1)); // [1]

// 添加或删除数组元素
console.log(a); // [1, 2, 3]
console.log(a.splice(0,1)); // [1]
console.log(a); // [2, 3]
console.log(a.splice(0,0,66)); // []
console.log(a); // [66, 2, 3]

// 删除并返回第一个元素
console.log(a.shift()); // 66

// 删除并返回最后一个元素
console.log(a.pop()); // 3

// 向数组开头添加元素
a.unshift(1)
console.log(a); // [1, 2]

// 向数组末尾添加元素
a.push(3)
console.log(a); // [1, 2, 3]

二、遍历方法

// forof遍历数组
for (const item of a) {
    console.log(item);
}
// 1
// 2
// 3
for (const [key,value] of a.entries()) {
// forof 不提供索引,但也有方法获取,entries()返回一个数组的迭代对象,该对象包含数组的键值对 (key/value)
    console.log(key);
}
// 0
// 1
// 2

// forin遍历对象
var obj = {
        name: 'test',
        color: 'red',
        day: 'sunday'
    }
for (const key in obj) {
    console.log(obj[key]);
}
// test
// red
// sunday
  • forEach、map和filter区别、find和filter区别
    // *forEach循环遍历,无返回值
    a.forEach((item,index) => {
        console.log(item);
    });
    // 1
    // 2
    // 3

    // *map循环遍历有返回值
    let sum = a.map((item,index)=>{
        return item+=10
    })
    console.log(sum); //[11, 12, 13]


    // filter遍历过滤,返回符合条件的元素
    let defrence = sum.filter((item,index) => item>11)
    console.log(defrence); //  [12, 13]

    // ****map 和 filter的区别
    // 1. map是原数组做映射,只会改变数组元素的值,不会改变数组长度
    // 2.filter是做过滤,只会改变数组长度,不会改变数组元素
    // 3.都是深拷贝,不会改变原数组
    
    // find返回符合条件的第一个元素,找到就停止执行
    console.log(a.find((item,index)=>{
        return item>1
    }));// 打印2没有打印3

    // findIndex 返回符合条件的第一个元素索引值
    console.log(a.findIndex(item=>{
        return item>1
    }));// 打印1没有打印2

    // ****find 和 filter的区别
    // 1. find返回符合条件的第一个元素,找到就停止执行,如果是数组对象,返回符合条件的对象
    // 2. filter返回符合条件的数组
  • some和every区别
    // 只要其一符合条件就返回true
    console.log(a.some((item,index)=>{
        return item>1
    })); // true

    // 只要有一个不符合条件就返回false
    console.log(a.every((item,index)=>{
        return item<1
    })); // false

    // ****someevery区别
    // every:一假即假,必须所有都返回true才会返回true,哪怕有一个false,就会返回false// some:一真即真, 只要其中一个为true 就会返回true
  • reduce做递归,但功能远不止如此
    var sumA = a.reduce((sumA,item) => {
        return sumA +=item
    },0)
    console.log(sumA); //6 累加 

三、合并对象

深拷贝:深拷贝的对象是将对象放进新的内存,两个对象变化互不影响。

浅拷贝:浅拷贝的对象共用一个内存地址,两个对象变化相互影响

// 1Object.assign()
var obj1 = {
    a:1,
    b:2
}
var obj2 = {
    c:1,
    d:2
}
console.log(Object.assign(obj1,obj2));//{a: 1, b: 2, c: 1, d: 2}
// obj1 = Object.assign(obj1,obj2)
// console.log(obj1);//{a: 1, b: 2, c: 1, d: 2} 这是深拷贝

///2、es6...扩展运算符
var obj3={
    ...obj1,
    ...obj2
}
console.log(obj3); // {a: 1, b: 2, c: 1, d: 2}

///3、forin 循环遍历 ,obj2.hasOwnProperty()返回*是否*有指定的键
for (const key in obj2) {
    if (obj2.hasOwnProperty(key)) {
        obj1[key] = obj2[key]
    }
}
console.log(obj1); // {a: 1, b: 2, c: 1, d: 2}

注意:当对象只有一层时,用Object.assign()是深拷贝,有第二层或多层时,用Object.assign()是浅拷贝

四、合并数组

// 求并集去重
// 第一种 es7 includes
let unicon = a.concat(b.filter(v => !a.includes(v)))
console.log(unicon); // [1, 2, 3, 4, 5]
// 第二种 es6 Array.from方法将类数组对象和可遍历对象转化为数组,Set 生成元素唯一的数据结构数组
console.log(Array.from('javascript')); // ['j', 'a', 'v', 'a', 's', 'c', 'r', 'i', 'p', 't']
console.log(Array.from(new Set(a.concat(b)))); // [1, 2, 3, 4, 5]
// 第三种 es6...扩展运算符
console.log(Array.from(new Set([...a,...b])));


// 求交集 
// 第一种 es7 includes
let intersection = a.filter(v => b.includes(v))
console.log(intersection);// [2]
// 第二种 es6 Array.from+Set+ filter + has过滤重复
console.log(Array.from(new Set(a.filter(v=> new Set(b).has(v))))); // [2]

// 求差集
// 第一种 es7 includes
let difference = a.concat(b).filter(v => !a.includes(v) || !b.includes(v))
console.log(difference); // [1, 3, 4, 5]
// 第二种 es6 Array.from+Set+ filter + has过滤非重复
console.log(Array.from(new Set(a.concat(b).filter(v=> !new Set(a).has(v) || !new Set(b).has(v))))); // [1, 3, 4, 5]

五、深拷贝

1.Object.assign()实现一层深拷贝

2.手写for循环拷贝

var obj9 = {
        a:1,
        b:2,
        c:{
            a:3
        }
    }
    //使用递归的方式实现数组、对象的深拷贝
    function deepClone(obj) {
        //判断拷贝的要进行深拷贝的是数组还是对象,是数组的话进行数组拷贝,对象的话进行对象拷贝
        var objClone = Array.isArray(obj) ? [] : {};
        //进行深拷贝的不能为空,并且是对象或者是
        if (obj && typeof obj === "object") {
            for (key in obj) {
                if (obj.hasOwnProperty(key)) {
                    if (obj[key] && typeof obj[key] === "object") {
                    objClone[key] = deepClone(obj[key]);
                    } else {
                    objClone[key] = obj[key];
                    }
                }
            }
        }
        return objClone;
    }

    var obj10 = deepClone(obj9)
    obj10.c = 100
    console.log(obj10); // {a: 1, b: 2, c: 100}
    console.log(obj9); // {a: 1, b: 2, c: {…}} 没有影响源数据

3.通过js的内置对象JSON来进行数组对象的深拷贝

    function deepClone2(obj) {
        var _obj = JSON.stringify(obj),
            objClone = JSON.parse(_obj);
        return objClone;
    }
    var obj11 = deepClone2(obj9)
    obj11.c = 100
    console.log(obj11); // {a: 1, b: 2, c: 100}
    console.log(obj9); // {a: 1, b: 2, c: {…}} 没有影响源数据