zoukankan      html  css  js  c++  java
  • 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)

  • 相关阅读:
    jprofiler配置
    Nginx编译安装
    WebBench的安装与使用
    你经常看到却经常忽视的__init__.py有什么用?
    彻底搞懂Python 中的 import 与 from import
    实现有过期时间的LRU缓存
    实现函数调用结果的 LRU 缓存
    elasticsearch Routing 路由详解
    Elasticsearch _reindex 接口来重新索引数据到新索引,使用新的配置
    浏览器操作elasticsearch别名
  • 原文地址:https://www.cnblogs.com/linewman/p/9918552.html
Copyright © 2011-2022 走看看