zoukankan      html  css  js  c++  java
  • 2020面试系列-js手写代码

    函数节流,防抖

     节流

    //函数节流
    function throttle(handler, wait) {
            let preTime = 0;
            return function () {
              let now = Date.now();
              if (now - preTime >= wait) {
                handler();
                preTime = now;
              }
            };
          }
          var t = throttle(function () {
            console.log(11);
          }, 1000);
          var oBtn1 = document.getElementById('btn1');
          oBtn1.onclick = function(){
              t();
          }
    
    

     防抖

    //函数防抖
    function debounce(handler, wait) {
            let timer = null;
            return function () {
              if(timer){
                  clearTimeout(timer);
              }
              timer = setTimeout(
                  handler,1000
              )
            };
          }
    
          var t = debounce(function () {
            console.log(11);
          }, 1000);
    
          document.onmousemove = function(){
              t();
          }
    

      

     

    实现call,apply,bind

    call

    Function.prototype.mcall = function (context) {
      //传参第一个参数转对象,不传参直接去window
      let ctx = Object(context) || window;
      let fn = "fn",
        res = "";
      while (ctx.hasOwnProperty(fn)) {
        // 循环判断并重新赋值 ,防止上下文对象上本来就有同名方法
        fn = fn + Math.random();
      }
      //把绑定函数作为上下文对象的方法
      ctx[fn] = this;
      //作为对象方法调用绑定函数,并把参数传入
      if (arguments.length > 1) {
        res = ctx[fn](...[...arguments].slice(1));
      } else {
        res = ctx[fn]();
      }
      delete ctx[fn];
      //返回函数返回值
      return res;
    };
    

    apply

    Function.prototype.mapply = function (context, arr) {
      let ctx = Object(context) || window;
    
      let fn = "fn",
        res = "";
      while (ctx.hasOwnProperty(fn)) {
        fn = fn + Math.random();
      }
    
      ctx[fn] = this;
    
      if (arr) {
        res = ctx[fn](...arr);
      } else {
        res = ctx[fn]();
      }
    
      delete ctx[fn];
      return res;
    };
    

    bind

    Function.prototype.mbind = function (context) {
      context = context ? Object(context) : window;
      //保存argumets
      var mArguments = arguments,
        self = this;
      if (arguments.length > 1) {
        return function () {
          //借用apply
          self.apply(context, [...mArguments].slice(1));
        };
      } else {
        return function () {
          self.apply(context);
        };
      }
    };
    

      

    实现数组实例方法

    push

    //push 从后面新增
    Array.prototype.push = functon(){
      for(var i =0;i<arguments.length;i++){
        this[this.length-1] = arguments[i];
      }
      return this.length;
    }  

    POP

    //pop 从后面删除一个
    Array.prototype.pop = function(){
      var item = this[this.length-1];
      if(this.length>0){
        this.length = this.length - 1;
      }
      return item;
    
    }
    

     shift

    //shift 从前面删除一项
    Array.prototype.shift = function(){
      var item = this[0];
      for(var i = 1;i<this.length;i++){
        this[i-1] = this[i];
      }
      this.length = this.length-1;
      return item;
    }

    unshrft

    //unshift 从前面增加n项
    Array.ptototype.unshift = function(){
      var l = arguments.length;
      //把原数组向后移动
      for(var i= 0;i<this.length;i++){
        this[i+l] = this[i];
      }
      //赋值
      for(var j = 0;j<arguments.length;j++{
        this[j] = arguments[j];
      }
      return this.length;
    }

     filter

    //fitler
    Array.prototype.fitler = function(handler){
      var newArr = [];
     for(var i = 0;i<this.length;i++){
       if(handler(this[i],i,this)){
        newArr[newArr.length] = this[i];
       }
     }
      return newArr;
    }
    

      

    数组去重

    //普通去重
    function unique(arr) {
      var newArr = [];
      arr.forEach((item, index, arr) => {
        if (newArr[newArr.length] != item) {
          newArr[newArr.length] = item;
        }
      });
      return newArr;
    }
    //indexOf去重
    function unique(arr) {
      var newArr = [];
      arr.forEach((item, inddex, arr) => {
        if (newArr.indexOf(item) == -1) {
          newArr.length = item;
        }
      });
      return newArr;
    }
    //利用对象属性不能相同
    function unique(arr) {
      var obj = {},
        newArr = [];
      arr.forEach((item, index, arr) => {
        if (!obj[item]) {
          obj[arr[i]] = 1;
          newArr.push(item);
        }
      });
      return newArr;
    }
    //es6去重
    function unique(arr) {
      return Array.from(new Set(arr));
    }
    //扩展运算符
    function unique(arr) {
      return [...new Set(arr)];
    }
    

      

    排序算法

    //冒泡排序
    //相邻两元素之间两两比较,比较出大值进行赋值互换,再依次与相邻的元素比较,层层递进
    //假设升序排序
    function bubbleSort(arr) {
      var l = arr.length;
      for (var i = 0; i < l; i++) {
        //比较轮数
        for (var j = 0; j < l - i - 1; j++) {
          //每一轮确定一个最大值,放最右边
          var temp = arr[j];
          if (arr[j] > arr[j + 1]) {
            arr[j] = arr[j + 1];
            arr[j + 1] = temp;
          }
        }
      }
      return arr;
    }
    
    //选择排序
    //先假设一个值为最大或者最小值
    
    function selectSort(arr){
      for(var i = 0;i<arr.length;i++){
        var minIndex = i; 
        for(var j = i;j<arr.length;j++){
          if(arr[j]>arr[j+1]){
            minIndex=j+1;
            var temp = arr[j];
            arr[j] = arr[j+1];
            arr[j+1] = temp;
          }
        }
      }
    
    }
    //快速排序
    //找基准,遍历数组,小于基准的放在left,大于基准的放在right,最后递归
    function quickSAort(arr){
      if(arr.length<=1>)return arr;
      var temp = arr[0],left=[],right =[];
      for(var i = 1;i<arr.length;i++){
        if(arr[i]<temp){
          left.push(arr[i])
        }else{
          right.push(arr[i])
        }
      }
      return [].concat(quickSort(left),temp,quickSort(right));
    }
    

      

    深拷贝

    //深拷贝黑科技
    JSON.parse(JSON.stringify(obj));
    //存在问题:无法拷贝原型上的属性和方法
    
    //递归实现
    function deepCopy(obj) {
      var newobj = obj.constructor === Array ? [] : {};
      if (typeof obj !== "object") {
        return obj;
      } else {
        for (var i in obj) {
          //判断对象的这条属性是否为对象,//若是对象进行嵌套调用,否则直接赋值
          newobj[i] = typeof obj[i] === "object" ? deepCopy(obj[i]) : obj[i];
        }
      }
      return newobj; //返回深度克隆后的对象
    }
    

      

    拉平多维数组

    //简便方法
    function flatArr(arr) {
      return arr.join(",").split(",");
    }
    //递归实现
    function flat(arr) {
      let arr1 = [];
      arr.forEach((val) => {
        if (val instanceof Array) {
          arr1 = arr1.concat(flat(val));
        } else {
          arr1.push(val);
        }
      });
      return arr1;
    }
    

      

    setTimeout模拟定时器

    function mInterval() {
      //要执行的逻辑
      console.log(1);
      //每次逻辑执行完,才会向队列添加事件
      setTimeout(mInterval, 1000);
    }
    
    mInterval();
    

      

    手写promise

    promise

    //判断变量是否是函数
    function isFunction(variable) {
      return typeof variable === "function";
    }
    
    //promise构造函数
    function MyPromise(handle) {
      if (!isFunction(handle)) {
        throw new Error("必须传入一个函数");
      }
      this.status = "pending"; //状态,默认等待状态
      this.value = ""; //值
      this.onResolveCallbacks = []; //存放成功回调的数组
      this.onRejectCallbacks = []; //存放失败回调的数组
      var that = this;
      try {
        handle(resolve, reject);
      } catch (err) {
        reject(err); //有报错,状态直接变为rejected
      }
    
      function resolve(val) {
        if (that.status == "pending") {
          that.status = "resolved";
          that.value = val;
          that.onResolveCallbacks.forEach((fn) => {
            fn();
          });
        }
      }
    
      function reject(err) {
        if (that.status == "pending") {
          that.status = "rejected";
          that.value = err;
          that.onRejectCallbacks.forEach((fn) => {
            fn();
          });
        }
      }
    }

     

    promise.then

    MyPromise.prototype.then = function (sucFun, faildFun) {
      //可选参数
      //如果没有传,只负责把值往后传
      sucFun = isFunction(sucFun) ? sucFun : (value) => value;
      faildFun = isFunction(faildFun) ? faildFun : (value) => value;
      var that = this;
      //先改变了状态
      if (this.status === "resolved") {
        sucFun(this.value);
      }
      if (this.status === "rejected") {
        faildFun(this.value);
      }
      //先指定了回调函数,状态还没改变
      if (this.status === "pending") {
        //存住回调函数,在异步操作完成时调用
        this.onResolveCallbacks.push(() => {
          sucFun(this.value);
        });
        this.onRejectCallbacks.push(() => {
          faildFun(this.value);
        });
      }
    
      return this;
    };
    

     promise.all

    Promise.allFun = (arr) => {
      return new Promise((resolve, reject) => {
        var resolveArr = [],
          rejectArr = [];
        for (var i = 0; i < arr.length; i++) {
          if (!(arr[i] instanceof Promise)) {
            arr[i] = Promise.resolve(arr[i]);
          }
          arr[i]
            .then((res) => {
              resolveArr.push(res);
              if (resolveArr.length == arr.length) {
                resolve(resolveArr);
              }
            })
            .catch((err) => {
              rejectArr.push(err);
              reject(rejectArr);
            });
        }
      });
    };
    

    promise.race

    myPromise.race = function (arr) {
      return new Promise(function (resolve, reject) {
        for (var i in arr) {
          arr[i].then(resolve, reject);
        }
      });
    };
    

      

    实现一个并发请求控制方法

    async function sendRequest(list, max = 4) {
      return new Promise((resolve, reject) => {
        let index = 0; //
        let count = 0; //上传成功个数
        const start = () => {
          while (max > 0 && index < list.length) {
            //剩余位置-1
            max--;
            let chunk = list[index];
            index++;
            request().then((res) => {
              max++; //释放暂用位置
              count++; //上传成功数量+1
              if (count == list.length) {
                resolve("完成了");
              } else {
                start();
              }
            });
          }
        };
    
        start();
      });
    }
    
    function request() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log(1);
          resolve(1);
        }, 2000);
      });
    }
    
    var list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1];
    sendRequest(list, 4)
      .then((res) => {
        console.log(res);
      })
      .catch((err) => {
        console.log("上传失败了");
      });
    

      

    实现new

    function new() {
      //创建空对象
      let obj = {};
      //获取构造函数
      let Constructor = Array.prototype.shift.call(arguments);
      //绑定原型关系
      obj.__proto__ = Constructor.prototype;
      // 执行构造函数,即绑定 this,并且为这个新对象添加属性
      Constructor.apply(newObj, arguments);
      //返回新对象
      return obj;
    }
    

      

    Object.create

    新创建一个对象,使用传入对象作为新对象的原型对象

    Object.create = function (obj) {
      //创建空构造函数F
      function F() {}
      //F的prottotype指向obj
      F.prtotype = obj;
      //返回F实例
      return new F();
    };
    

      

    输出数据类型

    function getType(param){
            if(param){
               return Object.prototype.toString.call(param).split(' ')[1].split(']')[0];
            }else{<br>       console.log('参数不能为空')<br>      }
     
         }

     斐波那契数列

    //给定位置,输出对应的值
    function fib(n){
            if(n==1||n==2){
                return 1;
            }
            return fib(n-1)+fib(n-2)
          }
    

      

  • 相关阅读:
    c#连接MySQL数据库
    MySQL下载与安装
    python简单页面爬虫入门 BeautifulSoup实现
    vue打包后.woff字体文件路径问题处理
    ReactNative真机运行
    前端知识总结--性能优化
    前端知识总结--ES6新特性
    我的开发框架(WinForm)4
    我的开发框架(WinForm)3
    我的开发框架(WinForm)2
  • 原文地址:https://www.cnblogs.com/liuxiaoru/p/13623020.html
Copyright © 2011-2022 走看看