一些手写js

用setTimeout 实现 setInterval (带清除定时器)

let time = 0;
let inter = setMyInter(()=>{
    time++;
    console.log(time)
},1000)

setTimeout(() => {
    inter.cancel();
}, 10000);
  
function setMyInter(fn,timeout){
    let time = null;
    function myInterval(){
        fn();
        time  = setTimeout(()=>{
            myInterval();
        },timeout);
    }
    myInterval();
    return {
        cancel:()=>{
            clearTimeout(time);
        }
    }
}

//增加执行方法入参的版本
let time = 0;
let inter = setMyInter((...val)=>{
    time++;
    console.log(val +" === " +time)
},1000,"haha","hehe")

setTimeout(() => {
    console.log('==finish==')
    inter.cancel();
}, 5000);
  
function setMyInter(fn,timeout,...args){
    let time = null;
    function myInterval(){
        let curArgs = Array.prototype.slice.call(arguments);
        console.log("1111=",curArgs);
        fn.apply(this,curArgs);
        time  = setTimeout(()=>{
            myInterval.apply(this,curArgs);
        },timeout);
    }
    console.log("1111=",args);
    myInterval.apply(this,args);
    return {
        cancel:()=>{
            clearTimeout(time);
        }
    }
}

setInterval缺陷 

1.setInterval对自己调用的代码是否报错漠不关心。即使调用的代码报错了,它依然会持续的调用下去 
2.setInterval无视网络延迟。在使用ajax轮询服务器是否有新数据时,必定会有一些人会使用setInterval,然而无论网络状况如何,它都会去一遍又一遍的发送请求,如果网络状况不良,一个请求发出,还没有返回结果,它会坚持不懈的继续发送请求,最后导致的结果就是请求堆积。 
3.setInterval并不定时。如果它调用的代码执行的时间小于定时的时间,它会跳过调用,这就导致无法按照你需要的执行次数或无法得到你想要的结果。

数组去重

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

数组扁平化

let arr2 = [1,[2,3],4,5,[6,[7,8]],9]
arr2 = flatter(arr2);
console.log(arr2);

function flatter(arr){
    let retArr = [];
    arr.forEach(element => {
      if(Array.isArray(element)){
        retArr = retArr.concat(flatter(element));
      }else{
        retArr = retArr.concat(element);
      }
    });
    return retArr;
}

手写call apply (bind有点复杂,先不写了...)

//apply 的所有参数都必须放在一个数组里面传进去 
Function.prototype.myApply = function(context,args){
    if(context == null){
        context = window;
    }
    let fn = Symbol(); //创造唯一的key
    context[fn] = this;//这里的this指的是当前的要执行的函数
    return context[fn](args);//执行 -- 返回执行结果
}

//call 的参数是直接放进去的,第二第三第 n 个参数全都用逗号分隔 ...组装成数组 就和apply一样了
Function.prototype.myCall = function(context,...args){
    if(context == null){
        context = window;
    }
    let fn = Symbol(); //创造唯一的key
    context[fn] = this;//这里的this指的是当前的要执行的函数
    return context[fn](args);//执行(因为用的是context执行的 所以里面的上下文已经是context) -- 返回执行结果
}

深拷贝

function deepClone(obj){
    if(obj == null || typeof obj !== 'object' ){
        //不是引用类型 是值类型
        return obj;
    }

    let result;
    if(obj instanceof Array){ //或者用 Array.isArray(obj)
        //是数组
        result = [];
    }else{
        result = {};
    }
    for(let key in obj){
        if(obj.hasOwnProperty(key)){
            result[key] = deepClone(obj[key]);
        }
    }
    return result;
}

koa洋葱模型

const middleware = []
let mw1 = async function (ctx, next) {
    console.log("next前,第一个中间件")
    await next()
    console.log("next后,第一个中间件")
}
let mw2 = async function (ctx, next) {
    console.log("next前,第二个中间件")
    await next()
    console.log("next后,第二个中间件")
}
let mw3 = async function (ctx, next) {
    console.log("第三个中间件,没有next了")
}


function use(mw) {
    middleware.push(mw)
}

use(mw1)
use(mw2)
use(mw3)

let fn = function (ctx) {
    return dispatch(0)

    function dispatch(i) {
        let currentMW = middleware[i]
        if(!currentMW) {
            return
        }
        return currentMW(ctx, dispatch.bind(null, i + 1))
    }
}

fn()
// output =>>>
// next前,第一个中间件
// next前,第二个中间件
// 第三个中间件,没有next了
// next后,第二个中间件
// next后,第一个中间件

 curry


function curry (fn, currArgs) {
    return function() {

        let args = [].slice.call(arguments);

        // 首次调用时,若未提供最后一个参数currArgs,则不用进行args的拼接
        if (currArgs !== undefined) {
            args = args.concat(currArgs);
        }

        // 递归调用   这里的fn.length表示的是fn 入参的个数
        if (args.length < fn.length) {
            return curry(fn, args);
        }

        // 递归出口
        return fn.apply(null, args);
    }
}
function sum(a, b, c) {
    console.log(a + b + c);
}

const fn = curry(sum);

fn(1, 2, 3); // 6
fn(1, 2)(3); // 6
fn(1)(2, 3); // 6
fn(1)(2)(3); // 6

防抖

let myinput = document.getElementById('myinput');

myinput.addEventListener('keyup',debounce(function(){
    console.log(myinput.value);
},500));

function debounce(fn , delay = 100){
    let timer = null;
    return function(){
        let context = this;
        if(timer){
            clearTimeout(timer);
        }
        timer = setTimeout(function() {
            fn.apply(context,arguments);
            timer = null;
        }, delay);
    }
}

节流

let drag = document.getElementById('drag');
drag.addEventListener('drag',throtte(function(e){
    console.log(e.offsetX,e.offsetY)
}),500);
function throtte(fn,delay = 100){
    let timer = null;
    return function(){
        let context = this;
        if(timer){
            return;
        }
        timer = setTimeout(() => {
            fn.apply(context,arguments);
            timer = null;
        }, delay);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
大学生就业服务平台管理系统按照操作主体分为管理员和用户。管理员的功能包括学生档案管理、字典管理、试卷管理、试卷选题管理、试题表管理、考试记录表管理、答题详情表管理、错题表管理、法律法规管理、法律法规收藏管理、法律法规留言管理、就业分析管理、论坛管理、企业管理、简历管理、老师管理、简历投递管理、新闻资讯管理、新闻资讯收藏管理、新闻资讯留言管理、学生信息管理、宣传管理、学生管理、职位招聘管理、职位收藏管理、招聘咨询管理、管理员管理。用户的功能等。该系统采用了Mysql数据库,Java语言,Spring Boot框架等技术进行编程实现。 大学生就业服务平台管理系统可以提高大学生就业服务平台信息管理问题的解决效率,优化大学生就业服务平台信息处理流程,保证大学生就业服务平台信息数据的安全,它是一个非常可靠,非常安全的应用程序。 管理员权限操作的功能包括管理新闻信息,管理大学生就业服务平台信息,包括考试管理,培训管理,投递管理,薪资管理等,可以管理新闻信息。 考试管理界面,管理员在考试管理界面中可以对界面中显示,可以对考试信息的考试状态进行查看,可以添加新的考试信息等。投递管理界面,管理员在投递管理界面中查看投递种类信息,投递描述信息,新增投递信息等。新闻信息管理界面,管理员在新闻信息管理界面中新增新闻信息,可以删除新闻信息。新闻信息类型管理界面,管理员在新闻信息类型管理界面查看新闻信息的工作状态,可以对新闻信息的数据进行导出,可以添加新新闻信息的信息,可以编辑新闻信息信息,删除新闻信息信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值