JS手写方法合集
2023年面试准备的手写方法合集。
排序相关
冒泡排序
function bubbleSort(arr){
let len = arr?.length
for(let i = 0; i < len; i++){
for(let j = 0; j < len - i - 1; j++){
if(arr[j] > arr[j + 1]){
arr[j] ^= arr[j + 1]
arr[j+1] ^= arr[j]
arr[j] ^= arr[j + 1]
}
}
}
console.log(arr, 'arr')
return arr
}
let result = bubbleSort(arr)
选择排序
function selectSort(arr) {
let len = arr?.length;
let minIndex = 0;
let temp
for(let i = 0; i < len - 1; i++) {
minIndex = i;
for(let j = i + 1; j < len; j++) {
if(arr[j] < arr[minIndex]){
minIndex = j
}
}
temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp
}
return arr
}
let arr = [7, 10, 2, 49, 20, 5]
let result = selectSort(arr)
console.log(result)
快排
function quickSort(nums) {
if(nums.length <=1) return nums;
let midIndex = Math.floor(nums?.length / 2);
let midValue = nums?.splice(midIndex, 1)?.[0]
let leftArr = [], rightArr = [];
nums.forEach(item => {
item < midValue ? leftArr.push(item) : rightArr.push(item)
})
return quickSort(leftArr).concat(midValue,quickSort(rightArr))
}
let result = quickSort([20,10,30,50,18,19])
有效括号
实现原理: 栈结构、map映射
function isValid(str) {
let stack = [];
let map = {
'{': '}',
'[': ']',
'(': ')'
}
for(let i in str){
let value = str[i]
if(value === '{' || value === '[' || value === '('){
stack.push(value)
}else {
let left = stack.pop(value)
let right = map[left]
if(value !== right){
return false
}
}
}
return stack?.length === 0
}
console.log(isValid("()")); // true
console.log(isValid("()[]{}")); // true
console.log(isValid("(]")); // false
console.log(isValid("([)]")); // false
console.log(isValid("{[]}")); // true
LRU
const LRUCache = function(capacity){
this.cache = new Map();
this.capacity = capacity;
}
LRUCache.prototype.get = function(key) {
if(this.cache.has(key)){
const value = this.cache.get(key)
this.cache.delete(key)
this.cache.set(key, value)
return value
}
return -1
};
LRUCache.prototype.put = function(key, value) {
if(this.cache.get(key)){
this.cache.delete(key)
}else{
if(this.cache.size >= this.capacity){
//空间满了
const firstKey = this.cache.keys().next().value
this.cache.delete(firstKey)
}
}
this.cache.set(key, value)
};
const lurCache = new LRUCache(2)
lurCache.put(1,1)
lurCache.put(2,2)
lurCache.get(1)
lurCache.put(3,3)
lurCache.get(2)
lurCache.put(4,4)
lurCache.get(1)
lurCache.get(3)
lurCache.get(4)
promise.all
function promiseAll (values) {
//参数必须为数组
if(!Array.isArray(values)){
return 'type error'
}
return new Promise((resolve, reject) => {
let resultArr = []; //返回结果
let idx = 0; //记录索引
for(let i in values){
const value = values[i];
if(value && typeof value?.then == 'function'){
//执行.then.catch
value?.then(res => processPromise(res, i)).catch(reject)
}else{
//直接拿结果
processPromise(value, i)
}
}
function processPromise(value, index) {
resultArr[index] = value
if(++idx === values?.length){
resolve(resultArr)
}
}
})
}
promiseAll([ new Promise(res => setTimeout(() => res(1), 1000)), 2,3]).then(res => console.log(res))
//输出 [1, 2, 3]
Primise.race
function promiseRace(values) {
if (!Array.isArray(values)) {
return Promise.reject('error type');
}
return new Promise((resolve, reject) => {
for (const data of values) {
if (data && typeof data?.then === 'function') {
data.then(res => {
resolve(res);
}).catch(error => {
reject(error);
});
} else {
resolve(data);
}
}
});
}
promiseRace([
new Promise(res => setTimeout(() => res(1), 2000)),
new Promise(res => setTimeout(() => res(2), 1000)),
new Promise(res => setTimeout(() => res(3), 3000))
]).then(res => console.log(res))
function promiseRace(values) {
if (!Array.isArray(values)) {
return Promise.reject('error type');
}
return Promise.race(
values.map(data => {
if (data && typeof data === 'function') {
return data();
} else {
return Promise.resolve(data);
}
})
);
}
promiseRace([
new Promise(res => setTimeout(() => res(1), 2000)),
new Promise(res => setTimeout(() => res(2), 1000)),
new Promise(res => setTimeout(() => res(3), 3000))
]).then(res => {
console.log(res);
}).catch(error => {
console.log(error);
});
bind
function bind(fn, thisArg) {
return function wrap() {
var args = new Array(arguments.length);
for (var i = 0; i < args.length; i++) {
args[i] = arguments[i];
}
return fn.apply(thisArg, args);
};
};
new关键字
new关键字实现原理
function _new(fn){
let obj = {}; // 创建对象
fn.call(obj); // 改变this指向
obj.__proto__ = fn.prototype; //原型指向原型对象
}
once函数实现
once函数为vue里面的once函数->函数只执行一次
实现原理:通过闭包的方式存储状态
function once(fn){
let state = false;
return () => {
if(!state) {
fn();
state = true
}
}
}
const onceFn = once(() => {
console.log('第一次')
})
onceFn()
onceFn()
onceFn()
字符串反转
function stringReverse(str){
return str.split("").reverse().join("")
}
数组随机排序
function arrayRandomSort(arr) {
}
arrayRandomSort([2,5,3,1])
统计字符串中出现次数最多的字符及次数
function getFrequentChar(str) {
let obj = {};
let maxArr = ['', 0]
for(let i of str) {
obj[i] = obj[i] ? obj[i] + 1 : 1
if(obj[i] > maxArr[1]){
maxArr = [i, obj[i]]
}
}
return maxArr
}
getFrequentChar("aaabbaaacc");
数组交集
function intersection(...arr) {
}
intersection([1, 2, 2], [1, 2, 2])
数组并集
function union(...arr) {
}
防抖
function debounce(fn, delay){
let timer = null;
return function(){
if(timer){
clearTimeout(timer)
}
timer = setTimeout(() => {
fn.apply(this, arguments);
timer = null
}, delay)
}
}
节流
1 节流时间戳方式实现
function throttle (fn, delay) {
var pre = 0;
return function () {
let now = Date.now();
if (now - pre >= delay) {
fn.apply(this, arguments)
pre = now;
}
}
}
2 节流定时器方式实现
function throttle (fn, delay) {
var statue = false;
return function(){
if(statue) {
return
};
statue = setTimeout(() => {
fn.apply(this, arguments);
statue = false;
}, delay)
}
}