• Array对象的方法实现(1)----Array.prototype.push和Array.prototype.concat(实现常规参数的功能)


    1,Array对象的push方法

    push 用于向数组的末尾添加一个或多个元素,并返回新的长度;改变原数组的长度,将新的值添加在数组的尾部

    语法:array.push(item1, item2, ..., itemX);

    注意:1,该方法的返回值是改变后的数组长度。2,原数组会改变。

    Array.prototype._push = function(item){
        //获取链接数组的参数param,同时用JSON可以深度拷贝数组
        let param = arguments, new_arr = JSON.parse(JSON.stringify(this)),len = new_arr.length;
        for(var i = 0;i < param.length; i++){
    	this[i + len] = param[i];
        }
        return this.length;
    }
    var pushArr = [1,2,3,4],pushArr0 = [1,2,3,4];
    console.log(pushArr.push(8,9,10));
    console.log(pushArr);
    console.log(pushArr0._push(8,9,10));
    console.log(pushArr0);

    输出都是改变后的数组长度7和改变后的数组[1,2,3,4,8,9,10]

    _push方法需要注意的是:

    (1,在当前数组添加元素的位置,是从this.length开始

    (2,最后返回的是数组改变后的长度

    (3,len必须放在循环外,如果放在循环内部,就会导致每次this.length是改变后的值(特别注意)

    2,Array对象的concat方法

    concat 用于链接两个或多个数组,不改变原数组,返回一个新的数组

    语法:array.concat(arr2,arr3,...,arrX);

    注意:1,返回一个新的数组。2,不改变原来的数组

    Array.prototype._concat = function(arr){
        //获取链接数组的参数param,同时用JSON可以深度拷贝数组
        let param = arguments, new_arr = JSON.parse(JSON.stringify(this));
    				
        for(let i = 0; i < param.length; i++){//遍历传入参数(数组)的个数
    	for(let k = 0; k < param[i].length; k++){//遍历当前参数(数组)的每一个值,同时将值放入新建数组
    	    new_arr._push(param[i][k]);
            }
        }
        return new_arr;//返回新建数组(多个数组链接完后的数组)
    }
    var hege = ["Cecilie", "Lone"];
    var stale = ["Emil", "Tobias", "Linus"];
    var kai = ["Robin"];
    var kai2 = ["Robin2"];
    console.log(hege.concat(stale,kai));
    console.log(hege);
    console.log(hege._concat(stale,kai,kai2));
    console.log(hege);

    arr.concat输出结果:

    ["Cecilie", "Lone","Emil", "Tobias", "Linus","Robin"]
    ["Cecilie", "Lone"]

    arr._concat输出结果:

    ["Cecilie", "Lone", "Emil", "Tobias", "Linus", "Robin", "Robin2"]
    ["Cecilie", "Lone"]


    _concat方法需要注意的是:

    (1,因为不改变元素组,所以需要用一个新的数组来接受

    (2,先遍历传入的参数个数,再遍历每个参数

    (3,返回的是新创建的数组

    3,Array对象的copyWithin方法
    copyWithin 用于从数组的指定位置拷贝元素到数组的另一个指定位置中

    语法:array.copyWithin(target, start, end);

    注意:1,返回一个数组。2,原数组改变

    Array.prototype._copyWithin = function(target, start, end){
        //获取链接数组的参数param,同时用JSON可以深度拷贝数组
        let param = arguments, new_arr = arr = JSON.parse(JSON.stringify(this));
    				
        if(param.length >= 2){
    	for(let i = 0; i < new_arr.length; i++){
    	    if(param[2]){
    	        if(i >= param[0] && i < param[0] + (param[2] - param[1])){
    		    this[i] = arr[param[1]];
    		    param[1]++;
    	        }
    	    }else{
    		if(i >= param[0] && i < this.length){
    		    this[i] = arr[param[1]];
    		    param[1]++;
    		}
    	    }
    						
    	}
        }
        return this;
    }
    			
    var copyArr = [1,2];
    var copyArr0 = [1,2];
    console.log(copyArr.copyWithin(1,0));
    console.log(copyArr);
    console.log(copyArr0._copyWithin(1,0));
    console.log(copyArr0);

    arr.copyWithin和arr._copyWithin输出:

    [1, 1]
    [1, 1]
    [1, 1]
    [1, 1]

    _copyWithin方法需要注意的是:

    (1,判断传入参数的个数,如果是3,也就是param[2]有效

    (2,判断开始复制的起始位置

    (3,改变的是数组本身

    修改后的_copyWithin方法:

    Array.prototype._copyWithin0 = function(target, start, end){
    	//获取链接数组的参数param,同时用JSON可以深度拷贝数组Array
    	let param = arguments, new_arr = arr = JSON.parse(JSON.stringify(this)),len = this.length;
    	
    	if(param.length >= 2 && (this[param[1]] || this[param[1]] === 0 || this[param[1]] === false)){
    		if(param[2] || param[2] === 0 || param[2] === false){
    			for(var i = param[0];i < param[0] + param[2] - param[1];i++){
    				this[i] = arr[param[1]++];
    			}
    		}else{
    			for(var i = param[0];i < len - param[0] - 1;i++){
    				this[i] = arr[param[1]++];
    			}
    		}
    	}
    	return this;
    }


    注意:

    (1,添加this[param[1]]有效,同时 this[param[1]] === 0和this[param[1]] === false的判断

    (2,添加param[2] === 0和param[2] === false的判断

    (3,将遍历放到判断内部,减少遍历的次数

    这个方法的判断还有很多不足,如果有发现的大神,请指正一下,谢谢!

    有点误人子弟,_push和_concat方法,我测过了,逻辑没问题。

    Mozilla:

    Array.prototype.copyWithin = function(target, start/*, end*/) {
        // Steps 1-2.
        if (this == null) {
          throw new TypeError('this is null or not defined');
        }
    
        var O = Object(this);
    
        // Steps 3-5.
        var len = O.length >>> 0;
    
        // Steps 6-8.
        var relativeTarget = target >> 0;
    
        var to = relativeTarget < 0 ?
          Math.max(len + relativeTarget, 0) :
          Math.min(relativeTarget, len);
    
        // Steps 9-11.
        var relativeStart = start >> 0;
    
        var from = relativeStart < 0 ?
          Math.max(len + relativeStart, 0) :
          Math.min(relativeStart, len);
    
        // Steps 12-14.
        var end = arguments[2];
        var relativeEnd = end === undefined ? len : end >> 0;
    
        var final = relativeEnd < 0 ?
          Math.max(len + relativeEnd, 0) :
          Math.min(relativeEnd, len);
    
        // Step 15.
        var count = Math.min(final - from, len - to);
    
        // Steps 16-17.
        var direction = 1;
    
        if (from < to && to < (from + count)) {
          direction = -1;
          from += count - 1;
          to += count - 1;
        }
    
        // Step 18.
        while (count > 0) {
          if (from in O) {
            O[to] = O[from];
          } else {
            delete O[to];
          }
    
          from += direction;
          to += direction;
          count--;
        }
    
        // Step 19.
        return O;
      };

    step1-2:判断this是否为空,如果为空,抛出错误,同时用object方法返回this对象        参考

    step3-5:对length取整     参考

    step6-8:获取relativeTarget,同时通过判断relativeTarget来获取to的值

    step9-11:获取relativeStart,同时通过判断relativeStart来获取from的值

    step12-14:获取relativeEnd,同时通过判断relativeEnd来获取final的值

    step15:获取需要拷贝的个数count

    step16-17:定义遍历参数从下向上direction = 1,如果从上向下遍历(direction = -1同时将to和from重新赋值从数组的最后一位开始)

    step18:while循环count>0,进行循环。如果from存在则拷贝,如果不存在就删除,count--,同时对to和from处理

    step19:返回O对象

    通过上边代码,我发现我写的代码太嫩了,考虑的太不全面了,不过先写着,慢慢学习,我相信多年过后来看自己的代码,总会看到进步。太难了,基本的都考虑不全面!!!

    相关链接:

    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin

    其他

    [我的博客,欢迎交流!](http://rattenking.gitee.io/stone/index.html)

    [我的CSDN博客,欢迎交流!](https://blog.csdn.net/m0_38082783)

    [微信小程序专栏](https://blog.csdn.net/column/details/18335.html)

    [前端笔记专栏](https://blog.csdn.net/column/details/18321.html)

    [微信小程序实现部分高德地图功能的DEMO下载](http://download.csdn.net/download/m0_38082783/10244082)

    [微信小程序实现MUI的部分效果的DEMO下载](http://download.csdn.net/download/m0_38082783/10196944)

    [微信小程序实现MUI的GIT项目地址](https://github.com/Rattenking/WXTUI-DEMO)

    [微信小程序实例列表](http://blog.csdn.net/m0_38082783/article/details/78853722)

    [前端笔记列表](http://blog.csdn.net/m0_38082783/article/details/79208205)

    [游戏列表](http://blog.csdn.net/m0_38082783/article/details/79035621)

  • 相关阅读:
    QFramework 使用指南 2020(二):下载与版本介绍
    QFramework 使用指南 2020 (一): 概述
    Unity 游戏框架搭建 2018 (二) 单例的模板与最佳实践
    Unity 游戏框架搭建 2018 (一) 架构、框架与 QFramework 简介
    Unity 游戏框架搭建 2017 (二十三) 重构小工具 Platform
    Unity 游戏框架搭建 2017 (二十二) 简易引用计数器
    Unity 游戏框架搭建 2017 (二十一) 使用对象池时的一些细节
    你确定你会写 Dockerfile 吗?
    小白学 Python 爬虫(8):网页基础
    老司机大型车祸现场
  • 原文地址:https://www.cnblogs.com/linewman/p/9918552.html
Copyright © 2020-2023  润新知