JavaScript-数组高级API

需求

要求遍历数组。

遍历

利用传统循环来遍历数组:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script>
        let arr = [1, 3, 5, 7, 9];

        for (let i = 0; i < arr.length; i++) {
            console.log(arr[i]);
        }
    </script>
</head>
<body>
</body>
</html>

利用 for in 循环来遍历数组:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script>
        let arr = [1, 3, 5, 7, 9];

        for (let key in arr) {
            console.log(key);
            console.log(arr[key]);
        }
    </script>
</head>
<body>
</body>
</html>

MDN:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/for...in

注意点:在企业开发中不推荐使用 for in 循环来遍历数组,for in 循环是专门用于遍历对象的,但是对象的属性是无序的,所以 for in 循环就是专门用于遍历无序的东西的,所以不推荐使用 for in 循环来遍历数组。

注意点:对象中的属性是无序的如下:

image-20211023091150176

For of

利用 ES6 中推出的 for of 循环来遍历数组:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script>
        let arr = [1, 3, 5, 7, 9];

        for (let value of arr) {
            console.log(value);
        }
    </script>
</head>
<body>
</body>
</html>

Array forEach

还可以利用 Array 对象的 forEach 方法来遍历数组,forEach 方法会自动调用传入的函数,每次调用都会将 当前遍历到的元素当前遍历到的索引当前被遍历的数组 传递给这个函数:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script>
        let arr = [1, 3, 5, 7, 9];

        arr.forEach(function (currentValue, currentIndex, currentArray) {
            // console.log(currentValue, currentIndex, currentArray);
            console.log(currentValue);
        });
    </script>
</head>
<body>
</body>
</html>

如果你对 Array 对象的 forEach 循环不是很理解,如下我贴出了它内部的实现原理你在来理解如上的代码,就和切菜没太大区别了实现原理代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script>
        let arr = [1, 3, 5, 7, 9];

        Array.prototype.myForEach = function (fn) {
            // this === [1, 3, 5, 7, 9]
            for (let i = 0; i < this.length; i++) {
                fn(this[i], i, this);
            }
        };
        arr.myForEach(function (currentValue, currentIndex, currentArray) {
            console.log(currentValue, currentIndex, currentArray);
        });
    </script>
</head>
<body>
</body>
</html>

查找

findIndex

数组的 findIndex 方法,findIndex 方法其实就是定制版的 indexOf,找到返回元素在数组当中的存放索引值,找不到返回 -1

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script>
        let arr = [1, 3, 5, 7, 9];

        let index = arr.findIndex(function (currentValue, currentIndex, currentArray) {
            // console.log(currentValue, currentIndex, currentArray);
            if (currentValue === 3) {
                return true;
            }
        });
        console.log(index);
    </script>
</head>
<body>
</body>
</html>

实现原理代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script>
        let arr = [1, 3, 5, 7, 9];

        // findIndex实现
        Array.prototype.myFindIndex = function (fn) {
            for (let i = 0; i < this.length; i++) {
                let result = fn(this[i], i, this);
                if (result) {
                    return i;
                }
            }
            return -1;
        }

        let index = arr.myFindIndex(function (currentValue, currentIndex, currentArray) {
            // console.log(currentValue, currentIndex, currentArray);
            if (currentValue === 3) {
                return true;
            }
        });
        console.log(index);
    </script>
</head>
<body>
</body>
</html>

find

数组的 find 方法,findIndex 方法返回索引,find 方法返回找到的元素,find 方法如果找到了就返回找到的元素,如果找不到就返回 undefined:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script>
        let arr = [1, 3, 5, 7, 9];

        let val = arr.find(function (currentValue, currentIndex, currentArray) {
            // console.log(currentValue, currentIndex, currentArray);
            if (currentValue === 3) {
                return true;
            }
        });
        console.log(val);
    </script>
</head>
<body>
</body>
</html>

实现原理代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script>
        let arr = [1, 3, 5, 7, 9];

        // find实现
        Array.prototype.myFind = function (fn) {
            for (let i = 0; i < this.length; i++) {
                let result = fn(this[i], i, this);
                if (result !== undefined) {
                    return this[i];
                }
            }
            return undefined;
        }

        let val = arr.myFind(function (currentValue, currentIndex, currentArray) {
            // console.log(currentValue, currentIndex, currentArray);
            if (currentValue === 3) {
                return true;
            }
        });
        console.log(val);
    </script>
</head>
<body>
</body>
</html>

过滤

filter

数组的 filter 方法,将满足条件的元素添加到一个新的数组中:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script>
        let arr = [1, 2, 3, 4, 5];

        let newArray = arr.filter(function (currentValue, currentIndex, currentArray) {
            // console.log(currentValue, currentIndex, currentArray);
            if (currentValue % 2 === 0) {
                return true;
            }
        });

        console.log(newArray);
    </script>
</head>
<body>
</body>
</html>

底层实现原理代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script>
        let arr = [1, 2, 3, 4, 5];

        // filter实现
        Array.prototype.myFilter = function (fn) {
            let newArray = [];
            for (let i = 0; i < this.length; i++) {
                let result = fn(this[i], i, this);
                if (result) {
                    newArray.push(this[i]);
                }
            }
            return newArray;
        }

        let newArray = arr.myFilter(function (currentValue, currentIndex, currentArray) {
            // console.log(currentValue, currentIndex, currentArray);
            if (currentValue % 2 === 0) {
                return true;
            }
        });

        console.log(newArray);
    </script>
</head>
<body>
</body>
</html>

map

数组的 map 方法,将满足条件的元素映射到一个新的数组中:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script>
        let arr = [1, 2, 3, 4, 5];

        let newArray = arr.map(function (currentValue, currentIndex, currentArray) {
            // console.log(currentValue, currentIndex, currentArray);
            if (currentValue % 2 === 0) {
                return currentValue;
            }
        });
        console.log(newArray);
    </script>
</head>
<body>
</body>
</html>

底层实现原理代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script>
        let arr = [1, 2, 3, 4, 5];

        // map实现
        Array.prototype.myMap = function (fn) {
            let newArray = new Array(this.length);
            newArray.fill(undefined);
            for (let i = 0; i < this.length; i++) {
                let result = fn(this[i], i, this);
                if (result !== undefined) {
                    newArray[i] = result;
                }
            }
            return newArray;
        }

        let newArray = arr.myMap(function (currentValue, currentIndex, currentArray) {
            // console.log(currentValue, currentIndex, currentArray);
            if (currentValue % 2 === 0) {
                return currentValue;
            }
        });
        console.log(newArray);
    </script>
</head>
<body>
</body>
</html>

删除数组元素注意点

需求:遍历的同时删除数组中的所有元素,在贴出实现代码之前实现我带你们来回顾一下删除的方式,可以利用 Array.splice 进行删除,还有一个就是数组本身其实就是一个对象,所以就可以利用 delete 也可以进行数组元素的删除,如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script>
        let arr = [1, 2, 3, 4, 5];

        arr.splice(2, 1);
        delete arr[0];
        console.log(arr);
    </script>
</head>
<body>
</body>
</html>

了解了有那些删除 API 之后接下来我们利用 for 进行遍历删除,实现来看看通过 splice 删除的结果:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script>
        let arr = [1, 2, 3, 4, 5];

        console.log(arr);
        for (let i = 0; i < arr.length; i++) {
            arr.splice(i, 1);
        }
        console.log(arr);
    </script>
</head>
<body>
</body>
</html>

浏览器运行结果如下,发现没有删干净如下图所示:

image-20211023113353785

没有删干净的原因就是数组的 length 是会根据你删除的元素动态进行改动的,如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script>
        let arr = [1, 2, 3, 4, 5];

        console.log(arr);
        //       0     0 < 5
        //       1     1 < 4
        //       2     2 < 3
        //       3     3 < 2
        for (let i = 0; i < arr.length; i++) {
            console.log(arr.length);
            arr.splice(i, 1);
        }
        console.log(arr);
    </script>
</head>
<body>
</body>
</html>

如上所说的就是数组删除的时候的一个注意点,那么我们知道了我们在删除元素的时候长度会进行改变造成没有循环到指定次数,我们这个时候就用一个变量来接收一下最初的长度进行遍历删除,代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script>
        let arr = [1, 2, 3, 4, 5];

        console.log(arr);
        let len = arr.length;
        for (let i = 0; i < len; i++) {
            console.log(len);
            arr.splice(i, 1);
        }
        console.log(arr);
    </script>
</head>
<body>
</body>
</html>

经过了改造之后的代码在浏览器运行结果发现还是没有删除干净,那么这又是为什么呢,我们已经循环了指定次数了为啥还没有删除干净呢?那么这里又有一个数组删除的时候的一个注意点,就是,例如你现在有三个元素,你把中间的一个元素删除了,最后的一个元素会往前推如下图所示:

test

如果要解决这个问题,那么我们往后面开始删它不就不会移动位置就能保证我们完美的进行删除全部元素啦,赶紧来实现一下吧,代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script>
        let arr = [1, 2, 3, 4, 5];

        console.log(arr);
        let len = arr.length;
        for (let i = len - 1; i >= 0; i--) {
            arr.splice(i, 1);
        }
        console.log(arr);
    </script>
</head>
<body>
</body>
</html>

如上是遍历删除元素的第一种方式,在来看看第二种方式吧如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script>
        let arr = [1, 2, 3, 4, 5];

        for (let i = 0; i < arr.length; i++) {
            console.log(arr.length);
            delete arr[i];
        }
        console.log(arr);
    </script>
</head>
<body>
</body>
</html>

注意点:通过 delete 来删除数组中的元素,数组的 length 属性不会发生变化,所以我如上的循环就没用用额外的变量去接收数组的长度了,其实通过 delete 删除元素其实就是把那个位置弄了个空的东西放在那里。

排序

数组的代码我将会以不同的数组作为案例来进行排序以及它们的注意点都会在代码里面体现。

示例一:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script>
        let arr = ["c", "a", "b"];
        // arr.sort();
        
        /*
        如果 compareFunction(a, b) 小于 0 ,那么 a 会被排列到 b 之前;
        如果 compareFunction(a, b) 等于 0 , a 和 b 的相对位置不变。
        如果 compareFunction(a, b) 大于 0 , b 会被排列到 a 之前
        注意点: 如果元素是字符串类型, 那么比较的是字符串的Unicode编码
        */
        arr.sort(function (a, b) {
            if (a > b) {
                return -1;
            } else if (a < b) {
                return 1;
            } else {
                return 0;
            }
        });
        console.log(arr);
    </script>
</head>
<body>
</body>
</html>

示例二:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script>
        let arr = [3, 4, 2, 5, 1];
        // arr.sort();

        arr.sort(function (a, b) {
            // if(a > b){
            //     return -1;
            // }else if(a < b){
            //     return 1;
            // }else{
            //     return 0;
            // }
            // 规律:如果数组中的元素是数值类型
            //      如果需要升序排序, 那么就返回a - b;
            //      如果需要降序排序, 那么就返回b - a;
            // return a - b;
            return b - a;
        });
        console.log(arr);
    </script>
</head>
<body>
</body>
</html>

示例三:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script>
        let arr = ["1234", "21", "54321", "123", "6"];
        arr.sort(function (str1, str2) {
            // return str1.length - str2.length;
            return str2.length - str1.length;
        });
        console.log(arr);
    </script>
</head>
<body>
</body>
</html>

示例四:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script>
        let students = [
            {name: "zs", age: 34},
            {name: "ls", age: 18},
            {name: "ww", age: 22},
            {name: "mm", age: 28},
        ];
        students.sort(function (o1, o2) {
            // return o1.age - o2.age;
            return o2.age - o1.age;
        });
        console.log(students);
    </script>
</head>
<body>
</body>
</html>

End

posted @ 2021-10-23 09:11  BNTang  阅读(60)  评论(0编辑  收藏  举报