ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] # 题1、如何获取数组中元素的个数? 答: length ~~~ [1,2,2,3,4].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\] ~~~ var arr = [1, 2, 2, 3, 4] ​ // 取出数组中的第 1 个元素,并且将这个元素从数组中删除 arr.shift(); console.log(arr);   // [ 2, 2, 3, 4 ] ​ // unshift 从数组的前面向数组中添加一个元素 arr.unshift(0); console.log(arr);   // [ 0, 1, 2, 2, 3, 4 ] ​ // pop 取出数组中最后一个元素,并且将这个元素从数组中删除 arr.pop(); console.log(arr);   // [ 1, 2, 2, 3 ] ​ // // push 往数组后面添加一个元素 arr.push(5); console.log(arr);   // [ 1, 2, 2, 3, 4, 5 ] ​ ~~~ # 题3、如何创建一个拥有 10 个元素的数组? 答:let arr = new Array(10) 知识点复习:创建数组至少有两种方法: ~~~ let arr = new Array()  // 创建空数组 let arr1 = []         // 创建空数组 ~~~ # 题4、如何用数组模拟栈结构? 答: 栈 是一种数据结构,特点: 后进先出(LIFO: Last In First Out)。 ![](http://ww1.sinaimg.cn/large/007WurYGgy1gf4zlwo39ej30e40a80uf.jpg) 可以使用 push 和 pop 实现入栈和出栈操作来模拟栈。 也可以使用 shift 和 unshift 实现入栈和出栈操作来模拟栈。 # 题5、如何用数组迷你队列结构? 答: 队列(queue)是一种数组,特点:先进先出(FIFO:Fist In First Out)。 ![](http://ww1.sinaimg.cn/large/007WurYGgy1gf4zphwn6xj30k808iq4b.jpg) 可以使用 push 和 shift 方法实现入队和出队来模拟队列。 也可以使用 unshift 和 pop 方法实现入队和出队来模拟队列。 # 题6、如何获取数组中最后一个元素的值? 答: 方法一、下标 arr\[ arr.length - 1\] (只获取不会删除最后一个元素) 方法二、arr.pop() (获取并删除最后一个元素) ~~~ // 获取数组中最后一个元素的值 var arr = [1, 2, 2, 3, 4] ​ // 方法一、 arr[arr.length - 1] (只获取不会删除最后一个元素) var a = arr[arr.length - 1] console.log(a); // 4 // 方法二、pop() 方法   (获取并删除最后一个元素) var b = arr.pop() console.log(b); // 4 ~~~ # 题7、如何把数组转成一个字符串? 答: 方法一、 join() 默认使用,隔开,也可以使用其他字符 方法二、toString() , 只能使用 , 隔开 ~~~ // 把数组转成一个字符串 var arr = [1, 2, 2, 3, 4] ​ // 方法一、 join() 默认使用,隔开,也可以使用其他字符 var a = arr.join('') console.log(a); // 1,2,2,3,4 // 方法二、toString() , 只能使用 , 隔开 var b = arr.toString() console.log(b); // 1,2,2,3,4 ~~~ # 题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) , 开始下标 ~ 结束下标 ,不修改原数组 ~~~ // 截取数组,比如:从数组中截取出第 2~5 个元素 var arr = [1, 2, 2, 3, 4, 5, 6, 7, 8, 9] // 方法一、 splice() 开始的下标 - 截取长度,修改原数组 var a = arr.splice(1, 4) console.log(a);     // [ 2, 2, 3, 4 ] console.log(arr);   // [ 1, 5, 6, 7, 8, 9 ] ​ // 方法二、 slice() 开始的下标 - 结束下标,不修改原数组 var b = arr.slice(1, 5) console.log(b);     // [ 2, 2, 3, 4 ] console.log(arr);   // [ 1, 2, 2, 3, 4, 5, 6, 7, 8, 9 ] ~~~ # 题9、如何删除数组中的元素? 答: splice 。 比如: 删除第二个元素: arr.splice(1,1) ~~~ // 删除数组中的元素 var arr = [1, 2, 2, 3, 4] arr.splice(1, 1) console.log(arr);   // [ 1, 2, 3, 4 ] ~~~ # 题10、如何对数组进行排序? 答:sort。 sort 可以用来对数组进行排序,但是使用时要注意:默认是 `按字符串` 进行排序的!! ![](http://ww1.sinaimg.cn/large/007WurYGgy1gf50enkgx2j30wg098ajp.jpg) 如何才能 `按数字` 来进行排序? 答:添加一个回调函数做为参数,这个回调函数有两个参数。 ![](http://ww1.sinaimg.cn/large/007WurYGgy1gf50eyzcd5j30ro0ds46k.jpg) 回调函数可以简写为箭头函数: ![](http://ww1.sinaimg.cn/large/007WurYGgy1gf50f4gazsj30f8074wh3.jpg) ~~~ // 对数组进行排序 // 使用 sort() var arr = [9, 23, 12, 123, 4, 8, 9, 10, 1, 7, 64, 34] // 升序 arr.sort(function (a, b) { return a - b }) // [ 1,   4, 7, 8, 9, 9, 10, 12, 23, 34, 64, 123 ] // 降序 arr.sort(function (a, b) { return b - a })  // [ 123, 64, 34, 23, 12, 10, 9, 9, 8, 7, 4, 1 ] // 简写为箭头函数 arr.sort((a, b) => a - b)   // [ 1,   4, 7, 8, 9, 9, 10, 12, 23, 34, 64, 123 ] ​ console.log(arr); ~~~ # 题11、什么是按引用传值?哪些遍历是按引用传值? 答:把一个变量在内存中的地址(引用)传过去。 对象类型(包含数组) 的数据都是按引用传值的。 ![](http://ww1.sinaimg.cn/large/007WurYGgy1gf50sue1rxj30l60e6adr.jpg) 特点: a和b现在操作的是内存中的同一个数组。 比如: ![](http://ww1.sinaimg.cn/large/007WurYGgy1gf50ttgy3sj30w00bowp7.jpg) 总结: 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() ~~~ 方法四、assign(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) // 15 ~~~ # 题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'] ~~~