📔
饥人谷前端体系课程笔记
黑马程序员笔记前端面试押题前端精进
  • 课程大纲
  • Git入门
    • 3. 软件安装详解
    • 4. Mac环境搭建
    • 5. 命令行入门
    • 6. 本地仓库
    • 7. Git远程仓库-GitHub
  • HTML全解
    • 8. HTML概览
    • 9. HTML标签
    • 10. HTML重难点
    • 11. HTML实践 & 手机调试
  • CSS全解
    • 12. CSS基础
    • 13. CSS布局(上)
    • 14. CSS布局(下)
    • 15. CSS定位
    • 16. CSS动画
  • HTTP全解
    • 17. URL 是什么
    • 18. 请求和响应 & Node.js Server
  • JS全解
    • 19. JavaScript概览
    • 20. 内存图与JS世界(精品课)
    • 21. Canvas 实践—画图板
    • 22. JS语法
    • 23. JS数据类型
    • 24. JS 对象
    • 25. JS 对象分类
    • 26. JS 数组
    • 27. JS 函数
    • 28. JS 实战,会动的代码
    • 29. JS运算符
    • 30. JS总结
  • JS编程接口
    • 31. DOM编程
    • 32. 手写DOM库
    • 33. JQuery中的设计模式(上)
    • 34. JQuery中的设计模式(下)
    • 35. DOM事件与事件委托
  • 项目 前端导航站点
    • 前端导航项目笔记
  • 前后分离
    • 40. AJAX的原理
    • 41. 异步与Promise
    • 42. 跨域、CORS、JSONP
    • 43. 静态服务器
    • 44. AJAX实战:Cookie、Session
  • JS进阶MVC
    • 48. MVC(上)
    • 49. MVC(中)
    • 50. MVC(下)
  • 项目构建
    • 51. Webpack(上)
    • 52. Webpack(下)
  • 算法与数据结构
    • 62. 伪代码与流程图
  • React全解
    • 75. React起手式
    • 76. React类组件和函数组件
    • 77. Class组件详解
    • 78. 函数组件
    • 79. Hooks原理解析
    • 80. Hooks各个击破
    • 81. 精通Redux
  • Node.js
    • 84. Node.js技术架构
    • 85. 文件模块
    • 86. 单元测试之文件模块
    • 87. 调试 Node.js 程序
    • 88. 静态服务器
    • 89. 命令行翻译工具
    • 90. 操作数据库
    • 91. 数据库基础知识
    • 92. Stream 流
    • 93. child_process
    • 94. 总结
  • TypeScript
    • 112. 基础
    • 113. 泛型
  • Next.js全解
    • Next.js 上
    • Next.js 下
  • ES6精讲
    • Promise,async/await
  • 大屏可视化笔记
    • 大屏可视化项目
  • SCSS全解
    • SCSS全解
  • 拓展
    • 一次性弄懂性能优化
    • Web性能优化
由 GitBook 提供支持
在本页
  • 26. JS 数组
  • 数组是什么
  • JS的数组不是典型数组
  • 典型的数组
  • 但JS的数组不这样
  • 创建一个数组
  • 新建
  • 转化
  • 伪数组
  • 合并两个数组,得到新数组
  • 截取一个数组的一部分
  • 增删改查
  • 删元素
  • 跟对象一样
  • 如果直接改length可以删元素吗?
  • 删除头部的元素
  • 删除尾部的元素
  • 删除中间的元素
  • 遍历数组
  • 查看所有元素
  • 查看所有属性名
  • 查看数字(字符串)属性名和值
  • forEach是一个槛
  • 自己写forEach才能理解forEach
  • 查看单个属性
  • 跟对象一样
  • 索引越界
  • 举例
  • 查找某个元素是否在数组里
  • 使用条件查找元素
  • 使用条件查找元素的索引
  • 增加数组中的元素
  • 在尾部加元素
  • 在头部加元素
  • 在中间添加元素
  • 修改数组中的元素
  • 反转顺序
  • 自定义顺序
  • 数组变换
  • .map
  • .filter
  • .reduce
  • 作业
  • 第一题
  • 第二题
  • 第三题
  • 面试题
  • 数据变换

这有帮助吗?

  1. JS全解

26. JS 数组

26. JS 数组

数组是什么

数组是一种特殊的对象

JS其实没有真正的数组,只是用对象模拟数组

JS的数组不是典型数组

典型的数组

元素的数据类型相同

使用连续的内存存储

通过数字下标获取元素

但JS的数组不这样

元素的数据类型可以不同

内存不一定是连续的(对象是随机存储的)

不能通过数字下标,而是通过字符串下标

这意味着数组可以有任何key,比如let arr = [1,2,3] ,arr['xxx'] = 1

创建一个数组

新建

let arr = [1, 2, 3]
let arr = new Array(1,2,3)
let arr = new Array(3)  //参数如果只有一个,表示的是长度

转化

let arr = '1,2,3'.split(',')//["1","2","3"]
let arr = '123'.split('')//["1","2","3"]
Array.from('123')//["1","2","3"]
Array.from({0:'a',1:'b',2:'c',3:'d',length:4})//["a","b","c","d"]要具备0,1,2,3这些下标和length才能生成数组

如何有0,1,2,但是长度是错的,会得到什么样的数组。

Array.from({0:'a',1:'b',2:'c',3:'d',length:2})
//["a","b"]
array = [1, 2, 3, 4, 5]//new Array(1,2,3,4,5)
array.__proto__ === Array.prototype//true

伪数组

let divList = document.querySelectorAll('div')

伪数组的原型链中并没有数组的原型,就是没有push这些,就是伪数组。

伪数组可以通过Array.from()来创建成数组。

合并两个数组,得到新数组

arr1.concat(arr2)

截取一个数组的一部分

arr1.slice(1)从第二个元素开始

arr1.slice(0)全部截取,经常用于浅拷贝/复制一个数组。

注意,JS只提供浅拷贝

let arr5 = [1,2,3,4,5,6,7,8,9]
arr5.slice(1)//[2,3,4,5,6,7,8,9]
arr5 //[1,2,3,4,5,6,7,8,9]

增删改查

删元素

跟对象一样

let arr = ['a','b','c']
delete arr['0']
arr //[empty,'b','c']
神奇,数组的长度并没有变
稀疏数组

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

let arr = [1,2,3,4,5];
arr.length = 1

我X,居然可以

JS真神奇

重要:不要随便改length

删除头部的元素

arr.shift()//arr被修改,并返回被删元素
let arr = [1,2,3]
arr.shift()//1
arr //[2,3]

删除尾部的元素

arr.pop()//arr被修改,并返回被删元素
let arr = [1,2,3]
arr.pop()//3
arr //[1,2]

删除中间的元素

arr.splice(index,1)//删除index的一个元素
let arr5 = [1,2,3,4,5,6,7,8]
arr5.splice(2,3)//[3,4,5]
arr5//[1,2,6,7,8]
//*****************************
arr.splice(index,1,'x')//
let arr6 = [1,2,3,4,5,6,7,8]//把6删掉改成666
arr6.splice(5,1,666)//6
arr6 //[1,2,3,4,5,666,7,8]
//*****************************
arr.splice(index,1,'x','y')//并在删除位置添加'x','y'
let arr7 = [1,2,3,4,5,6,7,8]
arr7.splice(5,1,666,777,888)//6
arr7 //[1,2,3,4,5,666,777,888,7,8]

遍历数组

查看所有元素

查看所有属性名

let arr = [1,2,3,4,5]; arr.x = 'xxx'
Object.keys(arr)
for(let key in arr){console.log(`${key}:${arr[key]}`)}

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

let arr = [1,2,3,4,5]
//undefined
arr.x = 'x'
//'x'
Object.keys(arr)
//(6) ['0', '1', '2', '3', '4', 'x']
Object.values(arr)
//(6) [1, 2, 3, 4, 5, 'x']
for(let i = 0; i < arr.length; i++){
console.log(`${i}:${i]}`)
}
//你要让i从0增涨到length-1
for(let i in arr){
    console.log(i)
}
//0 1 2 3 4 x
for(let i = 0; i < arr.length;i++){
  console.log(i);
}
//0 1 2 3 4
for(let i = 0; i < arr.length;i++){
  console.log(`${i}:${arr[i]}`)
}
//0:1
//1:2
//2:3
//3:4
//4:5
arr.forEach(function(item,index){
console.log(`${index}:${item}`)
})
//forEach要接受回调函数
//也可以用forEach/map等原型上的函数
function forEach(array,fn){
for(let i = 0; i < array.length;i++){
fn(array[i])
}
}
forEach(['a','b','c'],function(){})
>undefined
forEach(['a','b','c'],function(){console.log('执行了一次')})
>执行了一次
>执行了一次
>执行了一次
>undefined
forEach(['a','b','c'],function(x,y,z){console.log(x,y,z)})
//a 0 ['a','b','c']
//b 1 ['a','b','c']
//c 2 ['a','b','c']

问:用for和forEach的区别是什么?

答:答题点,比如for能做到的,forEach做不到

大多数情况下,两者都一样,只有一种情况是不一样的,就是for里面有continue和break,而forEach则没有。

let arr = [1,2,3,4,5,6,7,8]
for(let i = 0; i < arr.length;i++){
console.log(`${i}:${arr[i]}`)
if(i===3){break;}
}
//0:1
//1:2
//2:3
//3:4
arr.forEach(x=>{console.log(x)})
//1 2 3 4 5 6 7 8

forEach是一个槛

自己写forEach才能理解forEach

function forEach(array,fn){
for(let i = 0;i < array.length;i++){
fn(array[i],i,array)
}
}

.forEach用for访问array的每一项

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

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

.forEach返回的是undefined

查看单个属性

跟对象一样

let arr = [111,222,333]
arr[0]

索引越界

arr[arr.length] === undefined
arr[-1] === undefined

举例

for(let i = 0 ; i < arr.length;i++){
console.log(arr[i].toString())
}

报错:cannot read property 'toString' of undefined

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

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

使用条件查找元素

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

使用条件查找元素的索引

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

增加数组中的元素

不要使用arr[x]= xxx这种方式在数组上添加元素

let arr = [1,2,3,4,5,6]
arr[100] = 100
//[1,2,3,4,5,6,empty*94,100]
//length是101

在尾部加元素

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'
arr.splice(index,0,'x','y')

修改数组中的元素

反转顺序

arr.reverse(0)//修改原数组
let arr = [1,2,3,4,5,6,7,8]
arr.reverse()//[8,7,6,5,4,3,2,1]
arr//[8,7,6,5,4,3,2,1]

如何反转字符串?

var str = 'abcde'
str.split('').reverse().join('')//'edcba'

自定义顺序

arr.sort((a,b)=>a-b)

只需要判断哪个大哪个小,排序的事情不用管

  • 0:一样大

  • 1:左边的大

  • -1:右边的大

let arr = [5,2,4,3,1]
arr.sort()//[1,2,3,4,5]
arr//[1,2,3,4,5]
arr.sort(function(a,b){
if(a>b){
return 1
}else if(a===b){
return 0
}else{
return -1
}
})//[1,2,3,4,5]
let arr = [
{name:'小明',score:99},{name:'小红',score:95},{name:'大黄',score:100}
]
arr.sort(function(a,b){
  if(a.score > b.score){
  return 1
  }else if(a.score === b.score){return 0}
   else{return -1}
})
//快速写法
arr.sort((a,b)=>{
return a.score - b.score
})

数组变换

三个非常重要的数组变换函数.map, .filter, .reduce,都是返回新数组,不会改变原数组

.map

n变n,会返回新数组,不会改变原数组

let arr = [1,2,3,4,5,6]
arr.map(item => item * item)//[1,4,6,16,25,36]

.filter

let arr = [1,2,3,4,5,6]
arr.filter(item => item % 2 === 0 )//[2,4,6]

.reduce

reduce(callback,initialValue)
let arr = [1,2,3,4,5,6]
arr.reduce((sum,item)=>{return sum + item},0)

reduce是最屌的函数,有了reduce就不需要map,map只是个语法糖而已。

arr.reduce((result,item)=>{return result.concat(item*item)},[])

有了reduce,也不需要filter

let arr = [1,2,3,4,5,6]
arr.reduce((result,item)=>
result.concat(item % 2 === 1 ? [] : item)
,[])

作业

第一题

把数字变成星期

let arr = [0,1,2,2,3,3,3,4,4,4,4,6]
let arr2 = arr.map(补全代码)
console.log(arr2) // ['周日', '周一', '周二', '周二', '周三', '周三', '周三', '周四', '周四', '周四', '周四','周六']

第二题

找出所有大于60分的成绩

let scores = [95,91,59,55,42,82,72,85,67,66,55,91]
let scores2 = scores.filter(补全代码)
console.log(scores2) //  [95,91,82,72,85,67,66, 91]

第三题

算出所有数字之和

let scores = [95,91,59,55,42,82,72,85,67,66,55,91]
let sum = scores.reduce((sum, n)=>{
  补全代码
},0)
console.log(sum) // 奇数之和:598

面试题

数据变换

let arr = [
{名称:'动物',id:1,parent:null},
{名称:'狗',id:2,parent:1},
{名称:'猫',id:3,parent:1}
]
数组变成对象
{
id:1,名称:'动物',children[
{id:2,名称:'狗',children:null},
{id:3,名称:'猫',children:null},
]
}
arr.reduce((result,item)=>{
  if(item.parent === null){
    result.id = item.id
    result['名称'] = item['名称']
  }else{
    result.children.push(item)
    delete item.parent
    item.children = null
  }
  return result
},{id:null,children:[]})
上一页25. JS 对象分类下一页27. JS 函数

最后更新于3年前

这有帮助吗?

Screen Shot 2021-12-03 at 2.51.11 AM