前端面试必会手写的代码

662 阅读2分钟

1. instanceof

function myInstanceof (L, R) {
    if (L === null || typeof L !== 'object') return false
    let proto = Object.getPrototypeOf(L)
    // 可以换成
    // let proto = L.__proto__
    while (true) {
        if (proto === null) return false
        if (proto === R.prototype) return true
        proto = Object.getPrototypeOf(proto);
    }
}

// 测试代码:
let Car = function() {};
let BM = new Car();
console.log(myInstanceof(BM, Car)) // true

2.对象的深复制

function deepClone(source) {
    let parents = [];
    let children = [];
    function getRegExp(reg) {
      let result = "";
      if (reg.ignoreCase) {
        result += "i";
      }
      if (reg.global) {
        result += "g";
      }
      if (reg.multiline) {
        result += "m";
      }
      return result;
    }

    function _clone(parent) {
      if (parent === null) return null;
      if (typeof parent !== "object") return parent;
      var child, proto;
      if (Object.prototype.toString.call(parent) === "[object Array]") {
        child = [];
      } else if (Object.prototype.toString.call(parent) === "[object RegExp]") {
        child = new RegExp(parent.source, getRegExp(parent));
        if (parent.lastIndex) children.lastIndex = parent.lastIndex;
      } else if (Object.prototype.toString.call(parent) === "[object Date]") {
        child = new Date(parent.getTime());
      } else {
        // 处理对象原型
        proto = Object.getPrototypeOf(parent);
        child = Object.create(proto);
      }
      // 处理循环引用
      var index = parents.indexOf(parent);

      if (index !== -1) {
        // 如果父数组存在本对象, 说明之前已经被引用过,直接返回此对象
        return children[index];
      }
      parents.push(parent);
      children.push(child);

      for (const key in parent) {
        if (Object.hasOwnProperty.call(parent, key)) {
          child[key] = _clone(parent[key]);
        }
      }
      return child;
    }
    return _clone(source);
  }
  
  var origin = {
    a: 1,
    b: [2, 3, 4],
    c: {
      d: "xiaoxiang",
    },
    e: new RegExp("\d", "g"),
    f: new Date(),
    g: function () {
      console.log(this.a);
    },
  };
  origin.h = origin;

  var reslut = deepClone(origin);
  console.log(origin);
  reslut.b.push(5);
  reslut.c.d = "jjjjj";
  console.log(reslut);

3.冒泡排序

function sortA(arr) {
    for (var i = 0; i < arr.length - 1; i++) {
      for (var j = i + 1; j < arr.length; j++) {
        if (arr[i] > arr[j]) {
          var index = arr[j];
          arr[j] = arr[i];
          arr[i] = index;
        }
      }
    }
    return arr;
  }
  //demo:
  var numarr = [12, 18, 20, 19, 33, 9, 10, 6];
  console.log(sortA(numarr)); //[6, 9, 10, 12, 18, 19, 20, 33]  

4.快速排序

function sortB(arr) {
    if (arr.length <= 1) {
      return arr;
    } else {
      var len = Math.floor(arr.length / 2);
      var middlenum = arr.splice(len, 1);
      var left = [];
      var right = [];
      for (var i = 0; i < arr.length; i++) {
        if (arr[i] < middlenum) {
          left.push(arr[i]);
        } else {
          right.push(arr[i]);
        }
      }
    }
    return sortB(left).concat(middlenum, sortB(right));
  }
  //demo:
  console.log(sortB([12, 16, 20, 9, 8, 17, 10, 23])); //[8, 9, 10, 12, 16, 17, 20, 23]

5. 节流和防抖函数

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>节流和防抖函数</title>
  </head>
  <style>
    #box {
      width: 200px;
      height: 5000px;
      background-color: orange;
    }
  </style>
  <body>
    <input type="text" id="testInput" />
    <div id="box"></div>
    <script>
      /**
       * 节流
       * 常用的场景: window.resize window.onScroll onMouseMove 等等
       * */

      function jieliu(fn, text) {
        let canRun = true;
        return () => {
          if (canRun) {
            canRun = false;
            setTimeout(() => {
              fn(text);
              canRun = true;
            }, 1000);
          }
        };
      }

      function myfn(val) {
        console.log(1, val);
      }

      window.addEventListener("scroll", jieliu(myfn, "hhhh"));

      /**
       * 防抖
       * 常用的场景:input 输入
       * */

      function fangdou(fn) {
        let timer = null;
        return function () {
          if (timer) {
            clearTimeout(timer);
          }
          timer = setTimeout(() => {
            fn();
          }, 300);
        };
      }

      function myfn2() {
        console.log("要请求了");
      }
      document.getElementById("testInput").oninput = fangdou(myfn2);
      //   document.getElementById("testInput").addEventListener("input", fangdou(myfn2))
    </script>
  </body>
</html>

6.斐波那契数列 ( 1,1,2,3,5,8... )

 function digui(index) {
    if (index < 0) {
      return 0;
    }
    if (index <= 2) {
      return 1;
    }
    return digui(index - 1) + digui(index - 2);
  }
  //demo:
  console.log(digui(5)); //5

7.数组去重

7.1 利用对象的键不能相同去重

function norepeat(arr) {
    var obj = {},
      newarr = [];
    for (var i = 0; i < arr.length; i++) {
      if (!obj[arr[i]]) {
        obj[arr[i]] = 1;
        newarr.push(arr[i]);
      }
    }
    return newarr;
  }
console.log(norepeat([1, 2, 1, 2, 3, 3, 1, 2])); //[1,2,3]

7.2 数组排序后相邻去除法

function loop(arr) {
    arr.sort();
    var newarr = [arr[0]];
    for (var i = 0; i < arr.length; i++) {
      if (arr[i] !== newarr[newarr.length - 1]) {
        newarr.push(arr[i]);
      }
    }
    return newarr;
}
console.log(loop([1, 4, 3, 1, 2, 3, 3, 1, 2])); //[1,2,3,4]

7.3 遍历数组用indexOf去重

function fn1(arr) {
    var newarr = [];
    for (var i = 0; i < arr.length; i++) {
      if (newarr.indexOf(arr[i]) == -1) {
        newarr.push(arr[i]);
      }
    }
    return newarr;
  }
console.log(fn1([1, 4, 3, 1, 2, 3, 3, 1, 2])); //[1, 4, 3, 2]

7.4 ES6提供的方法set

var newa = Array.from( new Set( [1, 4, 3, 1, 2, 3, 3, 1, 2]) );
console.log(newa);//[1, 4, 3, 2]
var newb = [...new Set( [1, 4, 3, 1, 2, 3, 3, 1, 2] )];
console.log(newb); //[1, 4, 3, 2]

8 阶乘 fn(5) = 54321

function fn(n) {
    if (n < 2) {
      return n;
    }
    return n * fn(n - 1);
}
console.log(fn(5));