数组重构03-fill , forEach , copyWithin

  /* 
            copyWithin(start , copystart , copyend )  改变原数组,将自身的某些元素复制到自身的其他地方,并且会修改原来位置的值为负值的元素值, 注意: 不会改变数组的长度 
            fill: 填充 fill(填充的数据,开始位置 , 结束位置) 没写开始结束位置,默认从零开始到结束,不会修改数组长度
                + 注意: 如果填充数据是引用类型的,填充的是引用地址,且地址相同
                + start ,end 为非数字时start == 0  end视为null 返回原数组
                + 修改原数组
        */

        // 重构copyWighin  应用场景不很多
        let arrCopywithin = ['a', 'b', 'c', , 'e']
        console.log(arrCopywithin.copyWithin(0, -3, -2)) // 空元素复制时也是空,而非undefined
        function arrayCopywhithin(arr, start, copyStart, copyEnd) {
            if (!arr || arr.constructor !== Array) throw new TypeError(arr + 'is not an Array')
            //条件进行判断,所有的位置只能是整数 , 切位置本身就代表数组中的索引位置, 非数字取零
            if (start === undefined) return arr
            if (copyStart === undefined) copyStart = 0
            if (copyEnd === undefined) copyEnd = arr.length
            start = ~~start
            copyStart = ~~copyStart
            copyEnd = ~~copyEnd
            if (start < 0) start = start + arr.length > 0 ? start + arr.length : 0
            if (copyStart < 0) copyStart = copyStart + arr.length > 0 ? copyStart + arr.length : 0
            if (copyEnd < 0) copyEnd = copyEnd + arr.length > 0 ? copyEnd + arr.length : 0
            // 暂存一个数组方便拷贝
            let arrCopy = []
            for (let i = 0; i < arr.length; i++) {
                i in arr ? arrCopy[arrCopy.length] = arr[i] : arrCopy.length++
            }
            // 防止修改数组的长度
            let len = copyEnd - copyStart > arr.length - start ? arr.length - start : copyEnd - copyStart
            for (let j = start; j < start + len; j++) {
                let cpidx = copyStart + j - start
                if (cpidx in arr) arr[j] = arrCopy[copyStart + j - start]
                else {
                    arr[j] = null
                    delete arr[j]
                }
            }
            return arr
        }

        // 重构fill  
        let arrFill = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        // console.log(arrFill.fill(0, 2, 2) ,arrFill)  // true 修改原数组
        function arrayFill(arr, num, start, end) {
            if (!arr || arr.constructor !== Array) throw new TypeError(arr + 'is not an Array')
            if (end && typeof end !== 'number') return arr
            if (arr.length === 0) return arr
            if (start === undefined) start = 0
            if (end === undefined) end = arr.length
            start = ~~start
            end = ~~end
            if (start < 0) start = start + arr.length > 0 ? start + arr.length : 0
            if (end < 0) end = end + arr.length > 0 ? end + arr.length : 0
            for (let i = start; i < end; i++) {
                // 防止修改数组的长度
                if (i < arr.length) arr[i] = num
                else break
            }
            // while(start < end){
            //     if(start < arr.length){
            //         arr[start] = num
            //     }else break
            //     start++
            // }
            return arr
        }
        console.log(arrayFill(arrFill, 0, 2, 15))

        /* 
            forEach : 便利数组,接受一个回调函数,可以接收三个参数: 当前元素itm,当前索引 index,当前对象本身 arr , 还可以接受一个this指向,表示指向当前对象
                + 不遍历空元素
                + 没有返回值,相对来说,遍历适用多,一般不会修改元素值
                + 如果要修改元素的值,普通数据类型的值,需要用到第二个和的三个参数才能修改,引用数据类型,可以直接用itm进行修改  
                + 实际上forEach不允许直接修改itm,而可以通过itm直接修改引用类型元素,也没有直接修改itm值,修改了itm指向地址中的数据  
        */

        let arrForEach = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        // 非严格模式下,毁掉函数的this指向window 
        // thisArg: 将forEach中的this指向thisArg 对象
        function arrayForEach(arr, fn, thisArg) {
            if (!arr || arr.constructor !== Array) return new TypeError(arr + ' is not an Array')
            if (!fn || typeof fn !== 'functio ') return new TypeError(fn + 'is not a function')
            for (let i = 0; i < arr.length; i++) {
                //每一次循环都是在指向一次接受的函数,至于函数具体干啥,自己定义
                if (i in arr) fn(arr[i], i, arr)
            }
        }

        arrayForEach(arrForEach , function(itm , index , arr){
            console.log(itm , index)
            // 此处的return,作用只是打断了当前的回调执行,并不是终止forEach执行,因为此函数要被掉用多次
            // 并且foreach中没有接受返回值,返回值也没用
            return itm
        })

        // forEach 就一定不能中断吗? 当然可以
        try{
            arrForEach.forEach(function (itm ,index ,arr){
                if(itm === '要终止的条件') throw new Error( '报错')
                console.log('此处写要执行的东西')
            })
        }catch(e){}

        // 继续向后执行的代码不会受影响

你可能感兴趣的:(js,重构,javascript,前端)