JS常见手写面试题总结

防抖

function debounce(func, wait, immediate) {   
	let timeout;    
	return function () {     
		let context = this;     
		let args = arguments;      
		if (timeout) clearTimeout(timeout);     
		if (immediate) {       
			let callNow = !timeout;       
			timeout = setTimeout(function () {         
				timeout = null;       
			}, wait);       
			if (callNow) func.apply(context, args);     
		} else {       
			timeout = setTimeout(function () { 
				func.apply(context, args);       
			}, wait);     
		}   
	}; 
}

节流

// 使用时间戳 
function throttle(func, wait) {   
	let preTime = 0;    
	return function () {     
		let nowTime = +new Date();     
		let context = this;     
		let args = arguments;      
		if (nowTime - preTime > wait) {       
			func.apply(context, args);       
			preTime = nowTime;     
		}   
	}; 
}  
// 定时器实现 
function throttle(func, wait) {   
	let timeout;    
	return function () {     
		let context = this;     
		let args = arguments;      
		if (!timeout) {       
			timeout = setTimeout(function () {         
				timeout = null;         
				func.apply(context, args);       
			}, wait);     
		}   
	}; 
}

快速排序

function sortArray(nums) {   
	quickSort(0, nums.length - 1, nums);   
	return nums; 
}  
function quickSort(start, end, arr) {   
	if (start < end) {     
		const mid = sort(start, end, arr);     
		quickSort(start, mid - 1, arr);     
		quickSort(mid + 1, end, arr);   
	} 
}  
function sort(start, end, arr) {   
	const base = arr[start];   
	let left = start;   
	let right = end;   
	while (left !== right) {     
		while (arr[right] >= base && right > left) {       
			right--;     
		}     
		arr[left] = arr[right];     
		while (arr[left] <= base && right > left) {       
			left++;     
		}     
		arr[right] = arr[left];   
	}   
	arr[left] = base;   
	return left; 
}

instanceof

// 这个手写一定要懂原型及原型链。 
function myInstanceof(target, origin) {   
	if (typeof target !== "object" || target === null) 
	return false;   
	if (typeof origin !== "function")     
	throw new TypeError("origin must be function");   
	let proto = Object.getPrototypeOf(target); 
	// 相当于 
	proto = target.__proto__; 
	while (proto) {     
		if (proto === origin.prototype) return true;     
		proto = Object.getPrototypeOf(proto);   
	}   
	return false; 
}

数组扁平化

重点,不要觉得用不到就不管,这道题就是考察你对 js 语法的熟练程度以及手写代码的基本能力。 
function flat(arr, depth = 1) {   
	if (depth > 0) {     // 以下代码还可以简化,不过为了可读性,还是....
		return arr.reduce((pre, cur) => {       
			return pre.concat(Array.isArray(cur) ? flat(cur, depth - 1) : cur);     
		}, []);   
	}   
	return arr.slice(); 
}

手写 reduce

先不考虑第二个参数初始值: 
Array.prototype.reduce = function (cb) {   
	const arr = this; //this就是调用reduce方法的数组 
	let total = arr[0]; // 默认为数组的第一项 
	for (let i = 1; i < arr.length; i++) {     
		total = cb(total, arr[i], i, arr);   
	}   
	return total; 
}; 
考虑上初始值: 
Array.prototype.reduce = function (cb, initialValue) {   
	const arr = this;   
	let total = initialValue || arr[0];   // 有初始值的话从0遍历,否则从1遍历 				
	for (let i = initialValue ? 0 : 1; i < arr.length; i++) {     
		total = cb(total, arr[i], i, arr);   
	}   
	return total; 
};

带并发的异步调度器 Scheduler

JS 实现一个带并发限制的异度调度器 Scheduler,保证同时运行的任务最多有两个。完善下面代码中的 Scheduler 类,使得以下程序能正确输出。 
class Scheduler {   
	add(promiseMaker) {} 
}  
const timeout = (time) => new Promise((resolve) => {     
	setTimeout(resolve, time);   
});  
const scheduler = new Scheduler(); 
const addTask = (time, order) => {   
	scheduler.add(() => timeout(time).then(() => console.log(order))); 
};  
addTask(1000, "1");
addTask(500, "2"); 
addTask(300, "3"); 
addTask(400, "4"); 
// output:2 3 1 4 // 一开始,1,2两个任务进入队列。 // 500ms 时,2完成,输出2,任务3入队。 // 800ms 时,3完成,输出3,任务4入队。 // 1000ms 时,1完成,输出1。 根据题目,我们只需要操作 Scheduler 类就行: 
class Scheduler {   
	constructor() {     
		this.waitTasks = []; // 待执行的任务队列 this.excutingTasks = []; 
		// 正在执行的任务队列 this.maxExcutingNum = 2; 
		// 允许同时运行的任务数量   
	}    
	add(promiseMaker) {     
		if (this.excutingTasks.length < this.maxExcutingNum) {       
			this.run(promiseMaker);     
		} else {       
			this.waitTasks.push(promiseMaker);     
		}   
	}    
	run(promiseMaker) {     
		const len = this.excutingTasks.push(promiseMaker);     
		const index = len - 1;     
		promiseMaker().then(() => {       
			this.excutingTasks.splice(index, 1);       
			if (this.waitTasks.length > 0) {         
				this.run(this.waitTasks.shift());       
			}     
		});   
	} 
}

去重

利用 ES6 set 关键字:

function unique(arr) { 
	return [...new Set(arr)]; 
} 

利用 ES5 filter 方法:

function unique(arr) { 
	return arr.filter((item, index, array) => { 
		return array.indexOf(item) === index; 
	}); 
} 

特别感谢知友的,原详情链接:https://www.zhihu.com/question/523701242/answer/2430900871

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值