企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
[toc] > 数组 API:[https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global\_Objects/Array](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array) # 题1、如何获取数组中元素的个数? 答:length。 比如: ~~~ [1,2,34].length ~~~ # 题2、shift、unshift、pop、push 四个方法是干什么用的? 答:shift:取出数组中的第 1 个元素,并且将这个元素从数组中删除。(弹出) 注意:通过下标 0也可以获取数组中的第一个元素,arr[0],区别是这种不会删除第1个元素 unshift: 从数组的前面向数组中添加一个元素。 比如:[1,2,3].unshift(4) --> [4,1,2,3] pop:取出数组中最后一个元素,并且将这个元素从数组中删除。(弹出) 注意:通过下标也可以获取数组中最后一企鲜红:arr[arr.length-1],区别是这种不会删除最后一个元素 push:从数组的后面向数组中添加一个元素。 比如:[1,2,3].push(0) --> [1,2,3,0] # 题3、如何创建一个拥有 10 个元素的数组? 答:let arr = new Array(10) 知识点复习:创建数组至少有两种方法: ~~~ let arr = new Array() // 创建空数组 let arr1 = [] // 创建空数组 ~~~ # 题4、如何用数组模拟栈结构? 答:栈(zhan)是一种数据结构,特点:后进先出(LIFO:Last In First Out)。 ![](https://img.kancloud.cn/a8/20/a820fd3c2fa59aa8dcb3034a6cff80bb_508x368.png) 可以使用 push 和 pop 实现入栈和出栈操作来模拟栈。 也可以使用 shift 和 unshift 实现入栈和出栈操作来模拟栈。 # 题5、如何用数组模拟队列结构? 答:队列(queue)是一种数组,特点:前进前出(FIFO:Fist In First Out)。 ![](https://img.kancloud.cn/26/92/2692b12ca2bedbda28770a2cb1b5176d_728x306.png) 可以使用 push 和 shift 方法实现入队和出队来模拟队列。 也可以使用 unshift 和 pop 方法实现入队和出队来模拟队列。 # 题6、如何获取数组中最后一个元素的值? 答: 方法一、下标 arr[ arr.length - 1] (只获取不会删除最后一个元素) 方法二、arr.pop() (获取并删除最后一个元素) # 题7、如何把数组转成一个字符串? 答:方法一、join 默认使用,隔开,也可以使用其他字符 方法二、toString , 只能使用 , 隔开 # 题8、如何截取数组,比如:从数组中截取出第 2~4 个元素? 答:方法一、splice [1,2,3,4,5,6,7,8].splice(1, 5) 开始下标 ~ 截取长度 ,修改原数组 方法二、slice , [1,2,3,4,5,6,7,8].slice(1, 5) , 开始下标 ~ 结束下标 ,不修改原数组 # 题9、如何删除数组中的元素? 答:splice。 比如删除第2个元素: arr.splice(1,1) # 题10、如何对数组进行排序? 答:sort。 sort 可以用来对数组进行排序,但是使用时要注意:默认是 `按字符串` 进行排序的!! ![](https://img.kancloud.cn/1a/6e/1a6e01cf6df970ea262ccb61618fb207_1168x332.png) 如何才能 `按数字` 来进行排序? 答:添加一个回调函数做为参数,这个回调函数有两个参数。 ![](https://img.kancloud.cn/35/95/35957d88a1083518401ca43b70b8ce10_996x496.png) 回调函数可以简写为箭头函数: ![](https://img.kancloud.cn/ba/81/ba811a8e4023ebc848d0e0a3b3945539_548x256.png) # 题11、什么是按引用传值?哪些变量是按引用传值? 答:把一个变量在内存中的地址(引用)传过去。 对象类型(包含数组)的数据都是按引用传值的。 ![](https://img.kancloud.cn/e7/d6/e7d6e6a2166f2e634547bd56180466bd_762x510.png) 特点:a和b现在操作的是内存中的同一个数组。 比如: ![](https://img.kancloud.cn/1a/81/1a811963ffd36b56e18e358cee800762_1152x420.png) 总结: 1. 对象和数组在传值是是按引用传值。(传完之后,多个变量名操作的是同一个值) 2. 其他类型(数字、字符串、布尔等)不是按引用传值,其他类型是复制一份然后传值,(传完之后,彼此互不影响,各操作各的) # 题12、引用的扩展面试题1? 请说出以下代码的输出结果 代码一、 ~~~ let a = "abc" let b = a // 不是引用传值,把 a 复制一份传给 b ,b 和 a 是两个独立的变量 b = 'hello' // b 和 a 是两个独立的变量,修改 b 不影响 a console.log(a) // 输出 abc console.log(b) // 输出 hello ~~~ 代码二、 ~~~ let a = [1,2,3] let b = a // 数组是按引用传值,把 a 在内存中的地址传给 b ,a 和 b 指向同一个数组 b[1] = 100 // 修改 b 中的值, a 也会改变,因为 a 和 b 指向同一个数组 console.log(a) // 输出 [1,100,3] console.log(b) // 输出 [1,100,3] ~~~ 代码三、 ~~~ let a = {name:'tom',age:10} let b = a // 对象是引用传值,把 a 在内存中的地址传给 b ,a 和 b 指向同一个对象 b.age++ // 修改 b 对象就是修改 a 对象 console.log(a.age) // 输出 11 console.log(b.age) // 输出 11 ~~~ # 题13、引用的扩展面试题2? 说出以下代码的输出结果: 代码一、 ~~~ let a = 'abc' function toUp(a) { a = a.toUpperCase() // 这里的 a 和函数外面的 a 没有任何关系 } toUp(a) // 不是按引用传递(按值传递),把 a 的值复制一份传到函数中,函数中的变量和 a 完全没有关系 console.log(a) // 输出 abc ~~~ 代码二、 ~~~ let a = [1,2,3] function toUp(a) { a[0] = 100 // 这个a 就是外面的 a ,所以修改这个,就是修改外面的 a } toUp(a) // 数组和对象都是按引用传递的,也就是说,函数中的 a 和外面的 a 是同一个 a console.log(a) // 输出 [100,2,3] ~~~ 上面两段代码函数参数中的 a 会给同学生造成误解,以为是同一个 a,其实 函数参数名是任意的, 代码一、 ~~~ let a = 'abc' function toUp(x) { x = x.toUpperCase() // 这里的 a 和函数外面的 a 没有任何关系 } toUp(a) // 不是按引用传递(按值传递),把 a 的值复制一份传到函数中,函数中的变量和 a 完全没有关系 console.log(a) // 输出 abc ~~~ 代码二、 ~~~ let a = [1,2,3] function toUp(x) { x[0] = 100 // 这个a 就是外面的 a ,所以修改这个,就是修改外面的 a } toUp(a) // 数组和对象都是按引用传递的,也就是说,函数中的 a 和外面的 a 是同一个 a console.log(a) // 输出 [100,2,3] ~~~ 当然还有一种情况:这个情况和引用没有关系,`变量作用域` 的问题: ~~~ let a = 'abc' function toUp() { a = a.toUpperCase() // 这个 a 就是外面的 a } toUp() console.log(a) // 输出 ABC ~~~ # 题14、数组是按引用传递的,无法直接复制,那么应该如何复制(克隆)出一个新数组? 答: 方法一、(ES6)可以使用 ES6 中展开(...)运算符。(一维好使) ~~~ let a = [1,2,3,4] let b = [...a] // 把 a 中的元素展开,赋给 b (复制了一份),a 和 b 是两个独立 的数组 b[0] = 100 // 不影响 a console.log(a) // [1,2,3,4] console.log(b) // [100,2,3,4] ~~~ 方法二、先转字符串再转回数组( **几维都好使**) ~~~ let a = [1,2,3,4] let b = JSON.parse(JSON.stringify(a)) // 复制克隆一份 b[0] = 100 console.log(a) console.log(b) ~~~ 方法三、slice(一维好使) ~~~ let a = [1,2,3,4] let b = a.slice() ~~~ 方法四、(ES6)(一维好使) ~~~ let a = [1,2,3,4] let b = [] Object.assign(b,a) // 把 a 的值克隆一份给b ~~~ # 题15、如何合并两个数组? 答: 方法一、concat ~~~ let a = [1,2,3] let b = [3,4,5] let c = a.concat(b) ~~~ 方法二、... (ES6) ~~~ let a = [1,2,3] let b = [3,4,5] let c = [...a, ...b] ~~~ # 题16、请说出至少 10 个操作数组的方法? 答:concat:合并数组 join:转字符串 map:循环并修改数组中每个元素 filter:过滤数组 find:从数组中查找一个元素 findIndex:从数组中查找一个元素的下标 sort:排序 push:从后面添加元素 pop:从后面“弹出”元素 shift:从前面“弹出”元素 unshift:从前面添加元素 slice:截取数组(不删除) splice:截取并从数组中删除 reverse:反转数组元素的顺序 toString:转成字符串 toLocaleString:转字符串 forEach:循环数组中的元素 every(判断都满足):循环对数组中每个元素执行一个条件判断,如果所有的判断都返回 true ,那么最终结果是 true ,只要有一个是 false ,结果就是 false some(判断至少有一个满足):和 every 相反,只要数组中有一个满足条件就返回 true,如果全都不满足条件就返回 false ~~~ some 和 every 和对比 let a = [3,4,5,6,7] // 含义:every(每一个都满足):是否每一个都大于4 a.every(v=>v>4) // false // 含义:some(有至少一个满足):是否有至少一个大于4 a.some(v=>v>4) // true ~~~ reduce:循环处理数组中所有的元素,最后可以把每个结果累加到一起,返回最终结果。要会使用这个函数,首先要明确参数的函数。 ~~~ let a = [1,2,3,4,5] // 参数一x、上一次计算的结果 // 参数二y、循环数组时的当前元素 // 参数三z、当前元素的下标 // 返回值:这一次的计算结果,这个结果会被当作下一次循环的累加结果(第一个参数) // 比较数组中求和: // 说明: return x+y 含义:上一次的累加结果(x) + 当前值,和做为下一次的累加结果 a.reduce( function(x,y,z){ return x+y }) 简写: a.reduce((a,b)=>a+b) ~~~ # 题17、有一个数组:['abc','bcd','cd'],如何将数组中每个元素的第 1 个字母变大写? 答: ~~~ let a = ['abc','bcd','cd'] // 1. 向字符串对象的原型中添加一个方法,这样所有字符串就可以直接使用这个方法了 String.prototype.ucfirst = function() { // 转数组 let arr = this.split("") // ['a','b','c'] // 每1个元素大写 arr[0] = arr[0].toUpperCase() // ['A','b','c'] // 转字符 return arr.join("") // 'Abc' } // 2.对数组中每个字符串都执行 ucFirst 方法 a = a.map(v=>v.ucfirst()) console.log(a) // ['Abc','Bcd','Cd'] ~~~ # 题18、如何对数组去重?能想到几种方法? 答: 方案一、最简单的使用 ES6 中的 Set 使用 ES6 中的 Set 这种数据类型。 Set(集合),特点:没有重复的数据。 思路:1. 先把数组转成一个集合(重复的数据就删除了) ---> let s = new Set( 数组 ) 2. 把集合转回数组 ----> [ ...s ] 方案二、(最笨的方法)双向循环,一个一个判断