Throttling, anti-shake, new function, currying, flat data, tree data

anti shake

  1. Anti-shake is only triggered once within a fixed period of time (that is, when clicking continuously, the stop time is greater than the specified value to trigger the event)
  2. Realized by timer and closure
function debounce(fun,ms=1000){
    
    
  let timer; // 定义开关,当它为false时,定时器启动,为true时,清除掉上一个定时器
  return function (...args){
    
    
    if(timer){
    
    
      clearTimeout(timer)
    }
    timer=setTimeout(()=>{
    
     // 启动定时器,规定的防抖时间到了后再执行
       fun.call(this,args)
       timer=null
     },ms)
    
  }
}
const task=()=>{
    
    
  console.log('大于设置时间间隔,事件触发')
}
const debounceTask=debounce(task,1000) // 定义事件函数,规定防抖事件为1000ms
/*
* 测试
* 当
* setInterval(()=>{
*  console.log('一直触发事件中')
*  debounceTask()
* },500)
* 也就是触发的频率大于规定的1000ms,控制台只打印’一直触发事件中‘,不会出现’大于设置时间间隔,事件触发‘
*/
setInterval(()=>{
    
    
  console.log('一直触发事件中')
  debounceTask()
},2000)
/*
* 这个触发频率大于1000ms,每个2000ms打印’一直触发事件中‘和’大于设置时间间隔,事件触发‘
*/

throttling

  1. Throttling is triggered every fixed event (that is, when you click continuously, no matter how often you click, an event is triggered every fixed event)
  2. It is also implemented with closure plus timer
function throttle(fun,ms=1000){
    
    
  let canRun=true // 定义开关,默认为true,会启动定时器,false时,在判断语句中结束掉进程
  return function (...args){
    
    
    if(!canRun){
    
     return } // 当canRun为false时触发,也就是已经有一个定时器执行着,就结束该进程;也就是在此处截断
    canRun=false // 将canRun的状态改为false,那么在里面定时器执行完毕之前不会再向后走,也就是阻止后面事件触发时响应
    setTimeout(()=>{
    
    
      fun.apply(this,args)
      canRun=true // 执行完毕后,允许后面事件进来响应
    },ms)
  }
}
const task=()=>{
    
    
  console.log('大于设置时间间隔,事件触发')
}
const throttleTask=throttle(task,1000)

/*
* 测试
* 虽然执行频率为500ms一次,但控制台依然1000ms打印一次’大于设置时间间隔,事件触发‘
* 控制台打印 
* 	一直触发事件中
*	一直触发事件中
* 	大于设置时间间隔,事件触发
* 	一直触发事件中
*	一直触发事件中
* 	大于设置时间间隔,事件触发
*/
setInterval(()=>{
    
    
  console.log('一直触发事件中')
  throttleTask()
},500)

Note: You can use lodash to complete anti-shake and throttling

new

  1. ES6 syntactic sugar class principle
function myNew(Func,...args){
    
    
  const instance={
    
    }
  if(Func.prototype){
    
     // 如果函数原型存在,将instance指向原型对象上去
    Object.setPrototypeOf(instance,Func.prototype)
  }
  const res=Func.apply(instance,args) // 调用构造器,并将内部的this用instance来代替
  if(typeof res==='function' || typeof res==='object' && typeof res===null){
    
     // 兼容处理下返回值
    return res
  }
  return instance

}
function  Person(name){
    
    
  this.name=name
}
Person.prototype.eat=function (){
    
    
  console.log(this.name+'吃饭')
}
const p1=myNew(Person,'jakc')
p1.eat()
// jack吃饭

Currying

  1. Function currying means that we pass in some parameters to a function, and then a function will be returned to receive the remaining parameters, and the returned function will be executed later
  2. Split one parameter of a function into two or more parameters
function curry(func){
    
    
  return function curried(...args){
    
    
 	 // 传入的参数大于等于原始函数func的参数个数,则直接执行该函数
    if(args.length >= func.length){
    
    
      return func.apply(this, args)
    }
    /**
	 * 传入的参数小于原始函数fn的参数个数时
	 * 则继续对当前函数进行柯里化,返回一个接受所有参数(当前参数和剩余参数) 的函数
	 */
    return function (...args2){
    
    
      return curried.apply(this,args.concat(args2))
    }
  }
}
function sum(a,b,c){
    
    
  return a+b+c
}
const curriedSum=curry(sum)

console.log(curriedSum(1,2,3))
console.log(curriedSum(1)(2,3))
console.log(curriedSum(1)(2)(3))
// 输出结果都为6

flat data

	const newArr=[
	{
    
    
		id: 'a', 
		pid: 0, 
		value: '陕西', 
		children:[
			{
    
    
				 id: 1,
				 pid: 'a', 
				 value: '西安', 
				 children:[
				 		{
    
    id: 301, pid: 1, value: '雁塔区'},
				 		{
    
    id: 302, pid: 1, value: '高新区'}
				 ]
			},
			{
    
    
				id: 2,
				pid: 'a', 
				value: '渭南',
				children:[]
			},
			{
    
    
				id: 3, 
				pid: 'a', 
				value: '咸阳',
				children:[]
			},
		]
	},
	{
    
    
		id: 'b', 
		pid: 0, 
		value: '广东',
		children:[
			{
    
    
				id: 11, pid: 'b', value: '广州',children:[]
			},
			{
    
    
				id: 12, pid: 'b', value: '深圳',children:[]
			},
			{
    
    
				id: 13, pid: 'b', value: '潮汕', children:[]
			}
		]
	}
]
function toLine(data,result=[]){
    
    
    data.forEach(item=>{
    
    
      if(item.children){
    
    
        result.push({
    
    
          id:item.id,
          pid:item.pid,
          value:item.value,
        })
        toLine(item.children,result)
      }else {
    
    
        result.push({
    
    
          id:item.id,
          pid:item.pid,
          value:item.value,
        })
      }
    })
    return result

  }

 toLine(newArr)

Flattened data

[
	{
    
    id: 'a', pid: 0, value: '陕西'},
	{
    
    id: 1, pid: 'a', value: '西安'},
	{
    
    id: 301, pid: 1, value: '雁塔区'},
	{
    
    id: 302, pid: 1, value: '高新区'},
	{
    
    id: 2, pid: 'a', value: '渭南'},
	{
    
    id: 3, pid: 'a', value: '咸阳'},
	{
    
    id: 'b', pid: 0, value: '广东'},
	{
    
    id: 11, pid: 'b', value: '广州'},
	{
    
    id: 12, pid: 'b', value: '深圳'},
	{
    
    id: 13, pid: 'b', value: '潮汕'},
]

tree data

var data=[
    {
    
    pid:0,id:'a',value:'陕西'},
    {
    
    pid:'a',id:1,value:'西安'},
    {
    
    pid:1,id:301,value:'雁塔区'},
    {
    
    pid:1,id:302,value:'高新区'},
    {
    
    pid:'a',id:2,value:'渭南'},
    {
    
    pid:'a',id:3,value:'咸阳'},
    {
    
    pid:0,id:'b',value:'广东'},
    {
    
    pid:'b',id:11,value:'广州'},
    {
    
    pid:'b',id:12,value:'深圳'},
    {
    
    pid:'b',id:13,value:'潮汕'},

  ];
  function  toTree(data,pid) {
    
    
    function tree(pid){
    
    
      let arr=[]
      data.filter(item=> {
    
    
        return item.pid === pid // 过滤下与传入的pid(最顶层的pid号)相等的item,也就代表是最顶层,
      }).forEach(item=>{
    
    
        arr.push({
    
    
          id:item.id,
          pid:item.pid,
          value:item.value,
          children:tree(item.id) // 递归调用tree,渲染相同id的一组
        })
      })
      return arr
    }
    return tree(pid)
  }

 const newArr=toTree(data,0) // 传入的0代表最顶层数据的pid是0
 

Tree structure after rendering

[
	{
    
    
		id: 'a', 
		pid: 0, 
		value: '陕西', 
		children:[
			{
    
    
				 id: 1,
				 pid: 'a', 
				 value: '西安', 
				 children:[
				 		{
    
    id: 301, pid: 1, value: '雁塔区'},
				 		{
    
    id: 302, pid: 1, value: '高新区'}
				 ]
			},
			{
    
    
				id: 2,
				pid: 'a', 
				value: '渭南',
				children:[]
			},
			{
    
    
				id: 3, 
				pid: 'a', 
				value: '咸阳',
				children:[]
			},
		]
	},
	{
    
    
		id: 'b', 
		pid: 0, 
		value: '广东',
		children:[
			{
    
    
				id: 11, pid: 'b', value: '广州',children:[]
			},
			{
    
    
				id: 12, pid: 'b', value: '深圳',children:[]
			},
			{
    
    
				id: 13, pid: 'b', value: '潮汕', children:[]
			}
		]
	}
]

おすすめ

転載: blog.csdn.net/weixin_64925940/article/details/125305725