JS基础(3)——手写数组原型函数 之 不改变原数组(push,pop,shift,unshift,reverse,fill)
11、Array.prototype.push
参数 element1,…,elementN
返回值 新length
可通过call/apply用于类数组
push
方法根据 length
属性来决定从哪里开始插入给定的值。如果 length
不能被转成一个数值,则插入的元素索引为 0,包括 length
不存在时。当 length
不存在时,将会创建它。
Array.prototype.myPush = function() {
if(this == undefined){
throw new TypeError('this is null or not defined');
}
if(isNaN(this.length)){
this.length = 0;
}
const len = arguments.length;
if(Array.isArray(this)){
for(let i = 0;i < len; i++){
this[this.length] = arguments[i];
}
}else if(typeof this === 'object'){
// 类数组可以用 call/apply 调用
for(let i = 0;i < len; i++){
this[this.length] = arguments[i];
this.length++;
}
}
return this.length;
}
Javascript: Array.prototype.push()的源码及一些思考
12、Array.prototype.pop
参数:无
返回值:从数组中删除的元素(当数组为空时返回 undefined)。
可通过call/apply用于类数组
pop
方法根据 length
属性来确定最后一个元素的位置。如果不包含length
属性或length
属性不能被转成一个数值,会将length
置为0,并返回undefined
。
Array.prototype.myPop = function() {
if(this == undefined){
throw new TypeError('this is null or not defined');
}
if(this.length == undefined){
this.length = 0;
return undefined;
}
const item = this[this.length-1];
this.length--;
if(!Array.isArray(this)){
delete this[this.length];
}
return item;
}
13、Array.prototype.shift
参数:无
返回值:从数组中删除的元素; 如果数组为空则返回undefined
shift
方法移除索引为 0 的元素(即第一个元素),并返回被移除的元素,其他元素的索引值随之减 1。如果 length
属性的值为 0 (长度为 0),则返回 undefined
。
通过call/apply用于类数组。但是对于没有 length 属性(从0开始的一系列连续的数字属性的最后一个)的对象,调用该方法可能没有任何意义。
Array.prototype.myShift = function() {
if(this == undefined){
throw new TypeError('this is null or not defined');
}
if(this.length = undefined){
this.length = 0;
return undefined;
}
const item = this[0],
len = this.length;
for(let i = 0; i < len - 1; i++){
this[i] = this[i+1];
}
this.length--;
if(!Array.isArray(this)){
delete this[this.length];
}
return item;
}
14、Array.prototype.unshift
参数:element1, …, elementN
返回值:length属性值
通过 call
或 apply
方法作用于类数组对象上。不过对于没有 length 属性的对象,调用该方法可能没有任何意义。
Array.prototype.myUnshift = function() {
if(this == undefined){
throw new TypeError('this is null or not defined');
}
if(this.length == undefined){
return undefined;
}
const addLen = arguments.length;
for(let i = this.length - 1, length = this.length + addLen - 1; i >= 0; i--, length--){
this[length] = this[i];
}
for(let i = 0; i < addLen; i++){
this[i] = arguments[i];
}
if(!Array.isArray(this)){
this.length = addLen + this.length;
}
return this.length;
}
15、Array.prototype.reverse
参数:无
返回值:颠倒后的数组,改变原数组。
reverse
方法颠倒数组中元素的位置,改变了数组,并返回该数组的引用。
可被 call或 apply于类似数组对象。对象如果不包含length属性,则该对象可能不会以任何有意义的方式运行。
Array.prototype.myReverse = function() {
if(this == undefined){
throw new TypeError('this is null or not defined');
}
if(this.length == undefined){
return undefined;
}
const len = this.length;
for(let i = 0, j = len - 1; i < j; i++, j--){
[this[i], this[j]] = [this[j], this[i]];
}
return this;
}
16、Array.prototype.fill
语法:arr.fill(value[, start[, end]])
参数:value,用来填充数组元素的值;start,可选,起始索引,默认0;end,可选,终止索引,默认值 this.length
。
返回值:修改后的数组。
如果 start
是个负数, 则开始索引会被自动计算成为 length+start
。end
是个负数, 则 length+end
。
Array.prototype.myFill = function(value, start, end) {
if(this == undefined){
throw new TypeError('this is null or not defined')
}
if(!this.length || (start && isNaN(start)) || (end && isNaN(end))){
this.length = 0
return this
}
start = start ? start >= 0 ? start : start + this.length : 0
end = end ? end >= 0 ? end : end + this.length : this.length
if(start > this.length || end < 0){
return this
}else if(start < 0){
start = 0;
}else if(end > this.length){
end = this.length
}
for(let i = start; i < end; i++){
this[i] = value
}
return this
}