JS数组对象

简介: 数组对象-一种特殊的对象JS其实没有真正的数组-只是用对象模拟数组

数组对象

-一种特殊的对象

JS其实没有真正的数组

-只是用对象模拟数组

JS的数组不是典型数组

典型的数组

  1. 元素的数据类型相同
  2. 使用连续的内存存储
  3. 通过数字下表获取元素
  4. e5c02c48e2b8926d8302a76ae555fd9.png

但JS的数组不这样

  1. 元素的数据类型可以不同
  2. 内存不一定是连续的 (对象是随机存储的)
  3. 不能通过数字下标,而是通过字符串下标
  4. 这意味着数组有任何key比如
let arr = [1,2,3]
arr['xxx'] = 1
//这样也是可以的
复制代码

e33ea69b7c741feeec08195d5332054.png

创建一个数组

新建

let arr = [1,2,3]     //简写形式
let arr = new Array(1,2,3)  //正规形式,只是对理解数组有帮助
let arr = new Array(3)    //这里的3是长度,是length,而不是元素内容,多个写的时候才是内容
复制代码

转化

let arr = '1,2,3'.split(',')  //以,进行分割
let arr = '123'.split('')   //将每个元素直接分割
Array.from('123')       //直接就是['1','2','3']
复制代码

伪数组

let divList = document.querySelectorAll('div')
复制代码
  • 伪数组的原型链中并没有数组的原型
    应该是 数组 =>  数组原型 =>  对象原型
    伪数组是: 数组 =>   对象原型

没有数组共用属性的【数组】

-就是伪数组

合并两个数组,得到新数组
arr1.concat(arr2)
复制代码
截取一个数组的一部分
arr1.slice(1) //从第二个元素开始
arr1.slice(0) //全部截取
复制代码

注意:JS只提供浅拷贝

增删改查 -数组中的元素

删元素

跟对象一样

let arr = ['a','b','c']
delete arr['0']
arr //[empty , 'b' , 'c']
复制代码
  • 神奇,数组的长度没有变
    只是清除数据元素本身
    稀疏数组

如果直接改length可以删除元素吗

let arr = [1,2,3,4,5];
arr.length = 1;
复制代码
  • 我丢???这都可以
    JS就是这么神奇!!

删除头部的元素

arr.shift() //arr被修改,并返回被删元素
复制代码

删除尾部的元素

arr.pop() //arr被修改,并返回被删元素
复制代码

删除中间的元素

arr.splice(index,1) //删除index的一个元素
arr.splice(index,1,'x')//并在删除位置添加'x'
arr.splice(iindex,1,'x','y')//并在删除位置添加'x','y'
复制代码

查看所有元素

查看所有元素名

let arr = [1,2,3,4,5];   arr.x = 'xxx'
Object.keys(arr)
for(let key in arr){
  console.log(`${key} : ${arr[key]}`)
}
//for因访问对象居多
复制代码

查看数字(字符串)属性名和值

for(let i = 0; i< arr.length;i++){
  console.log(`${i} : ${arr[i]}`)
}
//查看数组较推荐
复制代码

你要自己让i从0增长到length-1

arr.forEach(function(item,index){
  console.log(`${index} : ${item}`)
})
复制代码

也可以用forEach/map等原型上的函数

forEach是一个坎

自己写forEach才能理解forEach

function forEach(array, fn) {
        for (let i = 0; i < array.length; i++) {
          fn(array[i], i, array)
        }
      }
forEach(['a', 'b', 'c'], function (值, 下标, 数组) {
        console.log(值, 下标, 数组)
 })
复制代码

forEach用for方位array的每一项

对每一项调用fn(array[i],i,array)

为什么要传入array呢?不为什么,规定如此

查看单个属性

跟对象一样

let arr= [111,22,3]
arr[0]  //是111
复制代码

索引越界

arr[arr.length] === undefined
arr[-1] === undefined
复制代码

举例

for(let i = 0 ; i<= arr.length; i++){
  console.log(arr[i].toString)
}
//会报错,因为  i <= arr.length
//最后会循环到 i[arr.length] 这一层,也就是会越界了
复制代码

报错Cannot read property 'toString' of undefined

意思是你读取了undefined的toString属性

不是toString是undefined

x.toString()其中x如果是undefined就会报这个错

查找某个元素是否在数组里

arr.indexOf(item)  //存在返回索引,否则返回-1
复制代码

使用条件查找元素

arr.find(item=> item%2 === 0) //找第一个偶数
复制代码

使用条件查找元素的索引

arr.findIndex(item => item%2 === 0)  //找第一个偶数的索引
复制代码

增加数组中的元素

在尾部加元素

arr.push(newItem) //修改arr,返回新长度
arr.push(item1,item2) //修改arr,返回新长度
复制代码

在头部加元素

arr.unshift(newItem) //修改arr,返回新长度
arr.unshift(item1,item2) //修改arr,返回新长度
复制代码

在中间添加元素

arr.splice(index,0,'x') //在index处插入'x'     0的意思是删除0个,也就是不删除
arr.splice(index,0,'x','y') //在index处插入'x','y'
复制代码

修改数组中的元素

反转顺序

arr.reverse() //修改原数组
复制代码

自定义顺序

arr.sort((a,b) => a-b)
接收两个参数 返回 1 0 -1
复制代码

map

map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值

map() 方法按照原始数组元素顺序依次处理元素。

例如可以返回原始数组中每个元素的平方:

let arr = [4, 9, 16, 25]
 let arr2 = arr.map( (item) =>      //唯一的参数是数组中的每个值
  Math.pow(item,2)                  //调用求平方方法
 )  
 console.log(arr2)  //[16, 81, 256, 625]
复制代码

也可返回一个数组的平方根:

let arr = [4, 9, 16, 25]
 let arr2 = arr.map( (item) =>      
  Math.sqrt(item)         //调用求平方根方法      
 )  
 console.log(arr2)   // [2, 3, 4, 5]
复制代码

注意:** map() 不会改变原始数组。

filter

filter() 方法创建一个新数组, 新数组中的元素是通过检查指定数组中符合条件的所有元素。

过滤掉太短的字符串:

const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];
const result = words.filter(word => 
  word.length > 6           //过滤掉小于6个字母的
);
console.log(result);      // ["exuberant", "destruction", "present"]
复制代码

过滤掉成绩不及格的分数:

let scores = [95,91,59,55,42,82,72,85,67,66,55,91]
let scores2 = scores.filter( item =>  
  item >60
)
console.log(scores2)   //[95, 91, 82, 72, 85, 67, 66, 91]
复制代码

注意:** filter() 也不会改变原始数组。

reduce

reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。

语法:

array.reduce( ( 初始值,当前元素, 当前元素的索引, 当前元素所属的数组对象) =>{
  //代码
}, 传递给函数的初始值)
必需。初始值, 或者计算结束后的返回值。    *******
必需。当前元素 **********             
可选。当前元素的索引
可选。当前元素所属的数组对象
可选。传递给函数的初始值   **********              
复制代码

算出所有奇数之和:

let scores = [95,91,59,55,42,82,72,85,67,66,55,91]
let sum = scores.reduce((sum, item)=>{ //sum是每轮相加后的保存者 item是当前元素
  if(item % 2){         
    return  sum += item         //如果是奇数,返回相加之和
  } 
  return sum   
},0)             //此0是规定sum的初始值               
console.log(sum)
复制代码

注意:就算不是奇数,我们也要返回sum本身,不能返回0,因为他每次接收到的值就是下一轮开始的值, 如果我们返回0,相当于把之前累加的都清空掉了

计算元素四舍五入后的和:

let arr = [15.5, 2.3, 1.1, 4.7]
let sum = arr.reduce((sum, item) => {  //首先还是sum,item。sum初始值在最后的0。
     return sum += Math.round(item)    
   }, 0)
console.log(sum)
复制代码

reduce是可以替代map与filter的。

替代map:  (计算数组中每个元素的平方,并返回新的函数)

let arr1 = [4, 9, 16, 25]
 let arr2 = arr1.reduce((arr2,item) => {//传入arr2数组,与arr1的每个元素
   return arr2.concat(Math.pow(item,2))                      
 },[])          //这里我们将arr2的初始值定位空数组
 console.log(arr2)  //[16, 81, 256, 625]
复制代码

注意://由于要返回数组,我们要arr2用concat这个方法连接arr1中的item元素,并返回 代替filter: (过滤掉太短的字符串)

let scores = [95,91,59,55,42,82,72,85,67,66,55,91]       
let scores2 = scores.reduce((scores2,item)=>{
    return scores2.concat(item>60?item:[])                                      个空数组,不能连接null,null会占位置
},[])
console.log(scores2)   //[95, 91, 82, 72, 85, 67, 66, 91]
复制代码

注意:如果大于60就连接到数组里,不然就连个空数组,不能连接null或undefined,null和undefined会占位置,变成['1',null,'2','3',null,'4']这个样子

总结

js中没有真正的数组,它的数组不是典型的数组

reduce在刚刚上手会比较难,多用几次就好了。

数组中最强大的就是splice和reduce,一定要用好这两个。

map()是n变n,即map里有多少元素,返回的数组就是多少元素,是对里面每个元素进行加功

filter()是n变少,过滤掉一些元素

reduce()是n变一,将所有元素进行累加



目录
相关文章
|
1月前
|
JavaScript 前端开发
如何在 JavaScript 中使用 __proto__ 实现对象的继承?
使用`__proto__`实现对象继承时需要注意原型链的完整性和属性方法的正确继承,避免出现意外的行为和错误。同时,在现代JavaScript中,也可以使用`class`和`extends`关键字来实现更简洁和直观的继承语法,但理解基于`__proto__`的继承方式对于深入理解JavaScript的面向对象编程和原型链机制仍然具有重要意义。
|
1月前
|
Web App开发 JavaScript 前端开发
如何确保 Math 对象的方法在不同的 JavaScript 环境中具有一致的精度?
【10月更文挑战第29天】通过遵循标准和最佳实践、采用固定精度计算、进行全面的测试与验证、避免隐式类型转换以及持续关注和更新等方法,可以在很大程度上确保Math对象的方法在不同的JavaScript环境中具有一致的精度,从而提高代码的可靠性和可移植性。
|
26天前
|
JSON 前端开发 JavaScript
JavaScript中对象的数据拷贝
本文介绍了JavaScript中对象数据拷贝的问题及解决方案。作者首先解释了对象赋值时地址共享导致的值同步变化现象,随后提供了五种解决方法:手动复制、`Object.assign`、扩展运算符、`JSON.stringify`与`JSON.parse`组合以及自定义深拷贝函数。每种方法都有其适用场景和局限性,文章最后鼓励读者关注作者以获取更多前端知识分享。
18 1
JavaScript中对象的数据拷贝
|
1月前
|
JavaScript 前端开发 图形学
JavaScript 中 Math 对象常用方法
【10月更文挑战第29天】JavaScript中的Math对象提供了丰富多样的数学方法,涵盖了基本数学运算、幂运算、开方、随机数生成、极值获取以及三角函数等多个方面,为各种数学相关的计算和处理提供了强大的支持,是JavaScript编程中不可或缺的一部分。
|
2月前
|
自然语言处理 前端开发 JavaScript
🛠️ JavaScript数组操作指南:20个精通必备技巧🚀
本文详细介绍了 JavaScript 中的 20 个高效数组操作技巧,涵盖了从基本的添加、移除元素,到数组转换和去重等高级操作。强调了不可变性的重要性,提供了清晰的代码示例,帮助开发者编写更整洁和高效的代码。无论是新手还是经验丰富的开发者,这些技巧都将显著提升您的编码能力,使您在项目中更具竞争力。
36 2
|
2月前
|
JavaScript 前端开发 测试技术
JS都有哪些操作数组的方法
JS都有哪些操作数组的方法
28 3
|
2月前
|
存储 JavaScript 前端开发
JavaScript 对象的概念
JavaScript 对象的概念
42 4
|
2月前
|
JavaScript
js删除数组中已知下标的元素
js删除数组中已知下标的元素
43 4
|
2月前
|
缓存 JavaScript 前端开发
JavaScript中数组、对象等循环遍历的常用方法介绍(二)
JavaScript中数组、对象等循环遍历的常用方法介绍(二)
47 1
|
2月前
|
存储 JavaScript 前端开发
js中函数、方法、对象的区别
js中函数、方法、对象的区别
21 2