本专栏相关链接
前端高频面试题1:HTML/CSS
前端高频面试题2:浏览器/计算机网络
前端高频面试题3:JavaScript
1.使用js实现对象打平
/* 有如下对象
const obj = {a: {b: {c: 1}},d: {e: 2,f: 3},g: 4
};
将上述对象打平成如下结构
{a.b.c: 1,d.e: 2,d.f: 3,g: 4
} */
function flatObject(obj, key = '') {let newObj = {}for(let k in obj) {const path = key ? `${key}.${k}` : kif(typeof obj[k] === 'object') {newObj = {...newObj, ...flatObject(obj[k], path)}} else {newObj[path] = obj[k]}}return newObj
}
const obj = {a: {b: {c: 1}},d: {e: 2,f: 3},g: 4
};
console.log(flatObject(obj));
2.使用js遍历二叉树(前序、中序、后序、层序遍历)
// 前序遍历 根左右
var preorderTraversal = function(root) {let arr = []if(root) {arr.push(root.val)if(root.left) arr.push(...preorderTraversal(root.left))if(root.right) arr.push(...preorderTraversal(root.right))}return arr
};
// 中序遍历 左根右
var inorderTraversal = function(root) {let arr = []if(root) {if(root.left) arr.push(...inorderTraversal(root.left))arr.push(root.val)if(root.right) arr.push(...inorderTraversal(root.right))}return arr
}
// 后序遍历:左右根
var postorderTraversal = function(root) {let arr = []if(root) {if(root.left) arr.push(...postorderTraversal(root.left))arr.push(root.val)if(root.right) arr.push(...postorderTraversal(root.right))}return arr
}
// 层序遍历
var levelOrder = function(root) {const ret = [];if (!root) {return ret;}//首先根元素入队//当队列不为空的时候// ·求当前队列的长度 s // ·依次从队列中取 s 个元素进行拓展,然后进入下一次迭代const q = [];q.push(root);while (q.length !== 0) {const currentLevelSize = q.length;ret.push([]);for (let i = 1; i <= currentLevelSize; ++i) {const node = q.shift();ret[ret.length - 1].push(node.val);if (node.left) q.push(node.left);if (node.right) q.push(node.right);}}return ret;
};
3.使用js实现一个有效括号的校验
var isValid = function(s) {const pairs = new Map([[')', '('],[']', '['],['}', '{']])let stk = [] // 使用栈s.split('').forEach(item => {if(pairs.has(item)) {if(!stk.length || stk[stk.length - 1] !== pairs.get(item)) {return false}stk.pop()} else {stk.push(item)}})return !stk.length
};console.log(isValid('([)]'));
4.如何使用js实现一个Promise.allSettled
function allSettled(promises) {const res = promises.map(promise => {return Promise.resolve(promise).then(value => ({ status: 'fulfilled', value }),reason => ({ status: 'rejected', reason }))})return Promise.all(res)
}const p1 = Promise.resolve(1);
const p2 = Promise.reject('Error');
const p3 = 42;allSettled([p1, p2, p3]).then(console.log);
5. 实现一个并发请求控制,同时最多请求n个,响应后补充一个,并实现可以通过await接收结果
function timeout(time,name) {return new Promise(resolve => {setTimeout(() => resolve(name), time)})
}class SuperTask {constructor(maxNum) {this.maxNum = maxNumthis.taskList = []this.runningTask = 0}add(task) {return new Promise((resolve, reject) => {this.taskList.push({task, resolve, reject});this._run()})}_run() {while(this.runningTask < this.maxNum && this.taskList.length) {const {task, resolve, reject} = this.taskList.shift()task().then(resolve, reject).finally(() => {this.runningTask--this._run()})this.runningTask++}}
}
const superTask = new SuperTask(2)
function addTask(time, name) {superTask.add(() => timeout(time, name)).then(res => {console.log(`任务${res}完成`);})
}addTask(10000, 1);
addTask(5000, 2);
addTask(3000, 3);
addTask(4000, 4);
addTask(5000, 5);