js数组Array基础【万字长文】

本文详细介绍了JavaScript中的数组创建、属性、方法,包括字面量与构造函数创建,length属性,以及push、pop、shift、unshift、splice、reverse、sort、fill、copyWithin等方法的使用及实现,帮助理解JavaScript数组操作。
摘要由CSDN通过智能技术生成

简介

JavaScript的 Array 对象是用于构造数组的全局对象,数组是类似于列表的高阶对象,用于在单个的变量中存储多个值。

创建数组

1.构造函数创建数组(new Array())
let arr = new Array();// 创建一个数组
let arr1 = new Array(7);// 创建一个长度为7的数组 只有一个元素时为数组长度
let arr2 = new Array([7]);// 创建一个数组,长度为1,第一个元素是7
let arr3 = new Array(1, 2, 3, 4);// 创建数组时赋值,元素个数多余一个时代表数组元素内容
2.字面量
let arr = []; // 创建一个空数组
let arr = [1, 2, 3, 4] // 创建数组并赋值

个人推荐使用字面量创建数组

数组属性

length 数组长度

length 属性表示数组的长度,即其中元素的个数。因为数组的索引总是由0开始,所以一个数组的上下限分别是:0和length-1。和其他大多数语言不同的是,JavaScript数组的length属性是可变的,这一点需要特别注意。当length属性被设置得更大时,将以空格将原先长度填满至指定length,仅仅是length属性变大;而为 length 赋一个更小的值则会删掉一部分元素。如:

let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
console.log(arr);  // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
console.log(arr.length); // 11
arr.length = 5 // 将arr的length长度属性设置为5,由于比原长度10小,因此arr最终只留下前5个元素,超过5长度的将被删除
console.log(arr); // [ 1, 2, 3, 4, 5 ]
console.log(arr[6]); // undefined 
arr.length = 8; // 上一步将length设置为5,现在将改变为8,大于5,因此将以空格来填充数组,直至将数组填满至8个长度
console.log(arr); // [ 1, 2, 3, 4, 5, , , ,]
prototype

Array.prototype 属性表示 Array 构造函数的原型,并允许您向所有Array对象添加新的属性和方法。

/*
如果JavaScript本身不提供 first() 方法,添加一个返回数组的第一个元素的新方法.
*/
if(!Array.prototype.first) {
    Array.prototype.first = function() {
        console.log(`如果JavaScript本身不提供 first() 方法,添加一个返回数组的第一个元素的新方法.`);
        return this[0];
    }
}
constructor

表示创建对象的函数。
object.constructor //object是对象或函数的名称。

let arr = [];
console.log(arr.constructor); // [Function: Array]

描述

访问数组元素

JavaScript 数组的索引是从0开始的,第一个元素的索引为0,最后一个元素的索引等于该数组的长度减1。如果指定的索引是一个无效值,JavaScript 数组并不会报错,而是会返回 undefined。

let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
console.log(arr[0]);  // 输出1
console.log(arr[1]);  // 输出2
console.log(arr[arr.length - 1]); // 输出10 arr.length-1最后一位
console.log(arr[arr.length - 1 + 1]); // 输出undefined

注意,数组元素可以看做是数组对象的属性,但是不能打点使用,否则会报语法错误,例如:

let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
console.log(arr.0); // a syntax error
let obj = { 007: '我是零零柒' }
console.log(obj.007); // 在对象中不可以这样引用,语法错误。
因为在 JavaScript 中,以数字开头的属性不能用点号引用,必须用方括号。
console.log(arr[0); // 输出1
console.log(obj[007]) // 输出‘我是零零柒’

在 JavaScript 中,以数字开头的属性不能用点号引用,必须用方括号。
在 JavaScript 中,以数字开头的属性不能用点号引用,必须用方括号。
在 JavaScript 中,以数字开头的属性不能用点号引用,必须用方括号。

数组方法

修改器方法(改变原数组)
pop()末位删除

方法从数组中删除最后一个元素,并返回该元素的值。此方法更改数组的长度。
语法:

arr.pop()

返回值删除的元素,当数组为空时返回undefined

let arr = [1, 2, 3, 4, 5]
console.log(arr.pop());  // 返回删除的末位元素5
console.log(arr);  // 删除后原数组已改变[ 1, 2, 3, 4 ]
let arr1 = [];
console.log(arr1.pop()); // undefined 当要执行pop()操作的数组为空时返回undefined
初步手动实现myPop()

Array.prototype.myPop=function (){
  let del = this.length  // 将要删除的元素保存下来
  this.length--; // 删除后数组长度减一
  return del // 返回删除的元素
}
let arr = [1,2,3,4]
console.log(arr.myPop()); // 被删除的元素4
console.log(arr);  // [ 1, 2, 3 ]

push()末尾增加

push() 方法将一个或多个元素添加到数组的末尾,并返回该数组的新长度。
语法

arr.push(element1, ..., elementN)

参数: (element1, …, elementN) 被添加到数组末尾的元素。
返回值改变后数组的长度

let arr = [1, 2, 3, 4, 5]
console.log(arr.push(6));  // 返回数组新长度6
console.log(arr);  // [ 1, 2, 3, 4, 5, 6 ]
console.log(arr.push(7,8,9,10)); // 返回数组新长度10
console.log(arr); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
初步实现myPush()
Array.prototype.myPush=function (){
  // 传进参数不止一个
  for(let i = 0; i < arguments.length; i++) {
    this[this.length] = arguments[i] //依次将要添加的元素添加到原数组最后
  }
  return this.length // 返回添加完后数组的长度
}
let arr = [1,2,3,4]
console.log(arr.myPush(1,2)); // 改变后数组长度6
console.log(arr);  // [ 1, 2, 3, 4, 1, 2 ]
shift() 首位删除

shift() 方法从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度
pop() 是前删,shift() 是后删
语法:

arr.shift()

返回值删除的元素,当数组为空时返回undefined

let arr = [1, 2, 3, 4, 5]
console.log(arr.shift());  // 返回删除的第一个元素1
console.log(arr);  // 删除后原数组已改变 [ 2, 3, 4, 5 ]
let arr1 = [];
console.log(arr1.shift()); // undefined 当要执行shift()操作的数组为空时返回undefined
初步实现myShift()
Array.prototype.myShift=function (){
  let del = this[0] // 将要删除的元素保存下来
  for(let i = 1; i < this.length; i++) {
    this[i - 1] = this[i] //从第二个元素开始依次往前挪一位
  }
  this.length-- // 删除后数组长度减一
  return del // 返回删除的元素
}
let arr = [1,2,3,4]
console.log(arr.myShift()); // 被删除的首位元素1
console.log(arr);  // 删除后数组变为[ 2, 3, 4 ]
unshift() 首位增加

unshift() 方法将一个或多个元素添加到数组的开头,并返回该数组的新长度(该方法修改原有数组)。
push()是后加,unshift() 是前加
语法

arr.unshift(element1, ..., elementN)

参数: (element1, …, elementN) 被添加到数组起始的元素。
返回值改变后数组的长度

let arr = [1, 2, 3, 4, 5]
console.log(arr.unshift(0));  // 返回数组新长度6
console.log(arr);  // [ 0, 1, 2, 3, 4, 5 ]
console.log(arr.unshift(11, 22, 33)); // 返回数组新长度9
console.log(arr); // [11, 22, 33, 0, 1, 2, 3, 4, 5]
初步实现myUnshift()
Array.prototype.myUnshift= function () {
  let arr = [...arguments, ...this] // 数组解构,将要添加的元素与原数组合并
  for (let i = 0; i < arr.length; i++) {
    this[i] = arr[i] // 遍历将合并后的数组赋值给原数组
  }
  return this.length // 返回改变后数组长度
}
let arr = [1, 2, 3, 4]
console.log(arr.myUnshift(1, 2, 3, 4, 2, 2)); // 返回改变后数组长度10
console.log(arr);  // 改变后数组变为[1, 2, 3, 4, 2, 2, 1, 2, 3, 4]

Array.prototype.myUnshift= function () {
  for (var i = this.length - 1; i >= 0; i--) {
    this[i + arguments.length] = this[i] //将原数组元素后移n位,n为要添加的元素个数
  }
  for (var j = 0; j < arguments.length; j++) {
    this[j] = arguments[j]; // 将要添加的元素赋值给数组前n项
  }
  return this.length // 返回改变后数组长度
}
let arr = [1, 2, 3, 4]
console.log(arr.myUnshift(1, 2, 3, 4, 2, 2)); // 返回改变后数组长度10
console.log(arr);  // 改变后数组变为[1, 2, 3, 4, 2, 2, 1, 2, 3, 4]
splice() 删除、插入和替换。

splice() 方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。
返回值: 删除的元素组成的数组
删除:指定 2 个参数:要删除的第一项的位置和要删除的项数。
语法:

arr.splice( start, deleteCount ) // 从第start项开始删除deleteCount 项

参数: start 定义从第几项开始删除,deleteCount定义要删除的项数

let arr = [1, 2, 3, 4, 5, 6, 7, 8];
console.log(arr.splice(1, 2)); // 返回删除项组成的数组[ 2, 3 ]
console.log(arr); // 删除后的数组[ 1, 4, 5, 6, 7, 8 ]
//如果只传start参数,则删除start后所有
console.log(arr.splice(1)); // 返回删除项组成的数组[ 4, 5, 6, 7, 8 ]
console.log(arr); // [1]
// 若start为负数,表示从数组末位开始的第几位,从-1计数,这意味着-n是倒数第n个元素并且等价于array.length-n
// 如果负数的绝对值大于数组的长度,则表示开始位置为第0位。
let arr1 = [1, 2, 3, 4, 5, 6, 7, 8];
console.log(arr1.splice(-1)); // 返回删除项组成的数组[ 8 ]
console.log(arr1.splice(-10)); // [1, 2, 3, 4, 5, 6, 7,]

插入:可以向指定位置插入任意数量的项
语法:

array.splice(start, 0, item1, item2, ...])

参数: 第一个参数start为起始位置,第二个参数为0,代表不删除,剩余参数代表要插入的项

let arr = [1, 2, 3, 4, 5];
console.log(arr.splice(1, 0, 9, 9 , 9)); // 返回[]空数组,未删除元素
console.log(arr); // [ 1, 9, 9, 2, 3, 4, 5 ]

替换:可以删除任意数量的元素,且同时向指定位置插入任意数量的元素,=》在某一位置删除并添加
语法:

array.splice(start, deleteCount, item1, item2, ...])

参数:start为起始位置,deleteCount为删除的个数,剩下的参数为要添加替换的元素

let arr = [1, 2, 3, 4, 5];
console.log(arr.splice(1, 2, 9, 9 , 9)); // 返回[ 2, 3 ]
console.log(arr); // [ 1, 9, 9, 9, 4, 5 ]
reverse() 反转、逆序

reverse() 方法将数组中元素的位置颠倒,并返回该数组。数组的第一个元素会变成最后一个,数组的最后一个元素变成第一个。该方法会改变原数组。
语法:

 arr.reverse()

返回值:颠倒后的数组。

let arr = [1, 2, 3, 4];
console.log(arr.reverse()); // [ 4, 3, 2, 1 ] 
console.log(arr); // [ 4, 3, 2, 1 ] 原数组改变
初步手动实现myReverse()
Array.prototype.myReverse = function () {
  for (let i = 0; i < this.length / 2; i++) {
    let temp = this[i]; // 将第i个元素保存
    this[i] = this[this.length - 1 - i]; // 将倒数第i个元素赋值给第i个元素
    this[this.length - 1 - i] = temp;   // 将temp(保存的第i个元素)赋值给倒数第i个元素
  }
  return this; // 返回修改后的数组
}
let arr = [1, 2, 3, 4]
console.log(arr.myReverse()); //[ 4, 3, 2, 1 ]

/*也可以将原数组倒序赋值给另一个数组,在赋值给原数组*/
Array.prototype.myReverse = function () {
  let copyArr = []
  for(let i = 0; i < this.length; i++) {
      copyArr[copyArr.length] = this[this.length - 1 - i]; // 将原数组倒序赋值给copyarr
  }
  for(let i = 0; i < copyArr.length; i++) {
      this[i] = copyArr[i]; // 将copyarr赋值给原数组
  }
  return this; // 返回修改后的数组
}

let arr = [1, 2, 3, 4]
console.log(arr.myReverse()); //[ 4, 3, 2, 1 ]

sort() 排序

sort() 方法用原地算法对数组的元素进行排序,并返回数组。默认排序顺序是在将元素转换为字符串,然后比较它们的UTF-16代码单元值序列时构建的
语法:

arr.sort([compareFunction(a, b)])

参数:compareFunction 指定排序方式的回调函数,如果省略,元素按照转换为的字符串的各个字符的Unicode位点进行排序。
返回值
对数组的引用。请注意,数组在原数组上进行排序,不生成副本。
mdn解释为排序后的数组。请注意,数组已原地排序,并且不进行复制。
字符串排序

const months = ['March', 'Jan', 'Feb', 'Dec'];
months.sort();
console.log(months); // [ 'Dec', 'Feb', 'Jan', 'March' ]

数字排序(需要指定回调函数)

function compareNumbers(a, b) { // 升序
  return a - b;
}
function compareNumbers(a, b) { // 降序
  return b - a;
}
let arr = [8, 5, 9, 0, 20, 36, 6];
arr.sort(function(a, b) {
  return a - b; //升序
})
console.log(arr); //[0,  5,  6, 8,9, 20, 36]
arr.sort((a, b) => a - b); //升序  箭头函数
console.log(arr); //[0,  5,  6, 8,9, 20, 36]
arr.sort(function(a, b) {
  return b- a; //降序
})
console.log(arr); // [ 36, 20, 9, 8, 6,  5, 0]
arr.sort((a, b) => b - a);  //降序  箭头函数
console.log(arr); // [ 36, 20, 9, 8, 6,  5, 0]

数组里面的元素是格式相同的对象排序

// 按照items 里面的value值进行升序排序
let items = [
  { name: 'Edward', value: 21 },
  { name: 'Sharpe', value: 37 },
  { name: 'And', value: 45 },
  { name: 'The', value: -12 },
  { name: 'Magnetic' },
  { name: 'Zeros', value: 37 }
];
items.sort((a, b)  => a.value - b.value );
console.log(items);
/*输出[
  { name: 'The', value: -12 },
  { name: 'Edward', value: 21 },
  { name: 'Sharpe', value: 37 },
  { name: 'And', value: 45 },
  { name: 'Magnetic' },
  { name: 'Zeros', value: 37 }
]
*/
/*
按照items 里name排序
items.sort(function(a, b) {
  // 忽略大小写
  var nameA = a.name.toUpperCase(); 
  var nameB = b.name.toUpperCase();
  if (nameA < nameB) {
    return -1;
  }
  if (nameA > nameB) {
    return 1;
  }
  // names must be equal
  return 0;
});
console.log(items);
输出[
  { name: 'And', value: 45 },
  { name: 'Edward', value: 21 },
  { name: 'Magnetic' },
  { name: 'Sharpe', value: 37 },
  { name: 'The', value: -12 },
  { name: 'Zeros', value: 37 }
]
*/
手动实现sort()

另开一篇单写排序

fill() 填充

fill() 方法用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。
语法:

array.fill(value, start, end)

参数:
value 必需,填充的值;
start 可选,起始索引,默认值为0;
end 可选,终止索引,默认array.length
返回值: 修改后的数组

//如果 start 是个负数, 则开始索引会被自动计算成为 length+start。如果 end 是个负数, 则结束索引会被自动计算成为 length+end。
[1, 2, 3].fill(4);               // [4, 4, 4]
[1, 2, 3].fill(4, 1);            // [1, 4, 4]
[1, 2, 3].fill(4, 1, 2);         // [1, 4, 3]
[1, 2, 3].fill(4, 1, 1);         // [1, 2, 3]
[1, 2, 3].fill(4, 3, 3);         // [1, 2, 3]
[1, 2, 3].fill(4, -3, -2);       // [4, 2, 3]
[1, 2, 3].fill(4, NaN, NaN);     // [1, 2, 3]
[1, 2, 3].fill(4, 3, 5);         // [1, 2, 3]
Array(3).fill(4);                // [4, 4, 4]
[].fill.call({ length: 3 }, 4);  // {0: 4, 1: 4, 2: 4, length: 3}
初步实现myFill()
Array.prototype.myFill = function (value, start = 0, end = this.length) {
  if (start < 0) { start = start + this.length }
  if (end < 0) { end = end + this.length }
  for (let i = start; i < end; i++) {
    this[i] = value;
  }
  return this
}
console.log([1, 2, 3].fill(4));           // [4, 4, 4]
console.log([1, 2, 3].fill(4, 1));         // [1, 4, 4]
console.log([1, 2, 3].fill(4, 1, 2));      // [1, 4, 3]
console.log([1, 2, 3].fill(4, 1, 1));       // [1, 2, 3]
console.log([1, 2, 3].fill(4, 3, 3));      // [1, 2, 3]
console.log([1, 2, 3].fill(4, -3, -2));     // [4, 2, 3]

copyWithin()

copyWithin() 方法浅复制数组的一部分到同一数组中的另一个位置,并返回它,不会改变原数组的长度。
语法:

array.copyWithin(target, start, end)

参数:
target必需,复制到指定目标索引位置;
start 可选,起始索引,默认值为0;
end 可选,终止索引,默认array.length
返回值: 修改后的数组

// 如果 start 为负,则其指定的索引位置等同于 length+start,length 为数组的长度。end 也是如此。
[1, 2, 3, 4, 5].copyWithin(-2)  // [1, 2, 3, 1, 2]
[1, 2, 3, 4, 5].copyWithin(0, 3)  // [4, 5, 3, 4, 5]
[1, 2, 3, 4, 5].copyWithin(0, 3, 4)	// [4, 2, 3, 4, 5]
[1, 2, 3, 4, 5].copyWithin(-2, -3, -1)	// [1, 2, 3, 3, 4]
初步实现myCopyWithin ()
Array.prototype.myCopyWithin = function (target, start = 0, end = this.length) {
  let obj = Object(this);
  var len = obj.length >>> 0;

  let relativeTarget = target >> 0
  let to = relativeTarget < 0 ? Math.max(relativeTarget + len, 0) : Math.min(relativeTarget, len)

  let relativeStart  = start  >> 0
  let from = relativeStart  < 0 ? Math.max(relativeStart  + len, 0) : Math.min(relativeStart , len)

  let relativeEnd  = end >> 0
  let final = relativeEnd  < 0 ? Math.max(relativeEnd  + len, 0) : Math.min(relativeEnd , len)

  let count = Math.min(final - from, len - to);
  let direction = 1;
  if (from < to && to < (from + count)) {
    direction = -1;
    from += count - 1;
    to += count - 1;
  }
  while (count > 0) {
    if (from in obj) {
      obj[to] = obj[from];
    } else {
      delete obj[to];
    }
    from += direction;
    to += direction;
    count--;
  }
  return obj;
}
console.log([1, 2, 3, 4, 5].myCopyWithin(-2));  // [1, 2, 3, 1, 2]
console.log([1, 2, 3, 4, 5].myCopyWithin(0, 2));  // [4, 5, 3, 4, 5]
console.log([1, 2, 3, 4, 5].myCopyWithin(0, 3, 8));	// [4, 2, 3, 4, 5]
console.log([1, 2, 3, 4, 5].myCopyWithin(-2, -3, -1));	// [1, 2, 3, 3, 4]

好了,今天就到这儿吧,小伙伴们点赞、收藏、评论,一键三连走起呀,下期继续更新数组不改变自身的方法~~

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值