JavaScript 中你需要知道的有关于数组的详细知识点
1、ES6 新增数组方法
Array.from()、Array.of()、copyWithin()、find()、findIndex()、fill()、entries()、keys()、values()、includes()。
2、ES5 新增数组方法
forEach()、map()、filter()、some()、every()、indexOf()、lastIndexOf()、reduce()、reduceRight()。
3、数组的这些方法,哪些能改变原数组?
copyWithin()、fill()、pop()、push()、reverse()、shift()、sort()、splice()。
4、some 和 every 有什么区别?
从中文含义能看出来,some 是某些,every 是每一个,它们都返回一个 Boolean 值。
5、数组里面有 10 万条数据,取第一个元素和第 10 万个元素哪个用时长?
用时基本上一样,因为 js 里面没有数组类型,数组其实也是一个对象,key 和 value。
6、数组去重你有几种方法?
1. 多层循环遍历法
- 双重
for循环; - 递归循环。
2. 利用语法自身键不可重复性或者API去重
ES6Set去重;- 新建空对象去重;
- 单层循环 +
filter/includes/indexOf; - 单层循环 +
Map、Object去重。
7、for 循环和 forEach 的性能哪个更好一点?
for 循环的性能更好
for循环没有任何额外的函数调用栈和上下文;forEach不是普通的for循环的语法糖,还有诸多参数和上下文需要在执行的时候考虑进来,这里可能拖慢性能。
8、sort 排序是按照什么方式来排序的?
默认排序顺序是在将元素转换为字符串,然后比较它们的 UTF-16 代码单元值序列时构建的。
9、多维数组转为一维数组
reduce递归实现join和split实现- 递归遍历
flat方法toString和split实现- 广度优先遍历/深度优先遍历
10、广度优先遍历和深度优先遍历如何实现
1. 深度优先遍历
- 访问顶点
v; - 依次从
v的未被访问的邻接点出发,对图进行深度优先遍历;直至图中和v有路径相通的顶点都被访问; - 若此时途中尚有顶点未被访问,则从一个未被访问的顶点出发,重新进行深度优先遍历,直到所有顶点均被访问过为止。
const depth = (node) => {
let stack = []
let nodes = []
if (node) {
stack.push(node)
while (stack.length) {
//每次取最后一个
let item = stack.pop()
let children = item.children || []
nodes.push(item)
//判断children的长度
for (let i = children.length - 1; i >= 0; i--) {
stack.push(children[i])
}
}
}
return nodes
}
2. 广度优先遍历
- 创建一个队列,并将开始节点放入队列中;
- 若队列非空,则从队列中取出第一个节点,并检测它是否为目标节点;
- 若是目标节点,则结束搜寻,并返回结果;
- 若不是,则将它所有没有被检测过的字节点都加入队列中;
- 若队列为空,表示图中并没有目标节点,则结束遍历。
const breadth = (node) => {
let nodes = []
let stack = []
if (node) {
stack.push(node)
while (stack.length) {
//取第一个
let item = stack.shift()
let children = item.children || []
nodes.push(item)
for (let i = 0; i < children.length; i++) {
stack.push(children[i])
}
}
}
return nodes
}
11、实现一个 reduce
Array.prototype.myReduce = function (fn, init) {
if (!init && this.length === 0) { // 如果数组长度为0
return this
}
let start = 1, pre = this[0]; // 从数组第二个开始下标为1
if (init !== undefined) { // 如果 init 字段存在,从第一个开始,下标为 0
start = 0;
pre = init;
}
for (let i = start; i < this.length; i++) { // 循环
let current = this[i]
pre = fn.call(this, pre, current, i, this) // 把每次的 reduce 的值返回
}
return pre
}
12、实现一个数组随机打乱的算法
function disOrder2 (arr) {
for (let i = 0; i < arr.length; i++) { // 遍历
const randomIndex = Math.floor(Math.random() * ary.length) // 生成随机数
swap(arr, i, randomIndex)
}
}
function swap(arr, i, _i) { // 交换
const tem = arr[i]
arr[i] = arr[_i]
arr[_i] = tem
}
arr = [1,2,3,4,5,6,7,8]
disOrder(arr)
console.log(arr)
13、给一串数字增加逗号分隔
1. 正则
num.replace(/(\d)(?=(\d{3})+(\.|$))/g, "$1,")
2. 遍历
function formatNumber(num) {
if (!num) return "";
let [int, float] = num.split(".");
let intArr = int.split("");
let result = [];
let i = 0;
while (intArr.length) {
if (i !== 0 && i % 3 === 0) {
result.unshift(intArr.pop() + ",");
} else {
result.unshift(intArr.pop());
}
i++;
}
return result.join("") + "." + (float ? float : "");
}
14、map、find、every、some、forEach 等方法的第二个参数是干什么的?
arr.every(callback(element[, index[, array]])[, thisArg])
thisArg执行callback时使用的this值。