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)

原文地址:https://www.cnblogs.com/linewman/p/9918552.html