JS手写方法合集


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)
    }
}

文章作者: echo_sixi
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 echo_sixi !
  目录