记录 30 seconds of code 项目个人觉得中有价值的片段或者小技巧(二)

请叫我海龟先生
• 阅读 1381

D - F 系列

1、防抖函数,限制高频触发

const debounce = (fn, ms = 0) => {
  let timeoutId;
  return function(...args) {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => fn.apply(this, args), ms);
  };
};
  • 可以运用在监听屏幕缩放,或者input 搜索时,做一些性能优化

2、转换首字母(或其他)大小写

const decapitalize = ([first, ...rest], upperRest = false) =>
  first.toLowerCase() +
  (upperRest ? rest.join('').toUpperCase() : rest.join(''));

decapitalize('FooBar'); // 'fooBar'
decapitalize('FooBar', true); // 'fOOBAR'
  • [first, ...rest] 通过这种解构的方式将字符分割成数组,同时获取到首字母

3、深克隆

const deepClone = obj => {
  if (obj === null) return null;
  let clone = Object.assign({}, obj);
  Object.keys(clone).forEach(
    key =>
      (clone[key] =
        typeof obj[key] === 'object' ? deepClone(obj[key]) : obj[key])
  );
  // 如果是数组仍然会转成 key - value 形式
  if (Array.isArray(obj)) {
    // 添加 length 属性,便于 Array.from 进行转换(类数组或者可迭代对象)
    clone.length = obj.length;
    return Array.from(clone);
  }
  return clone;
};

4、数组打平

const deepFlatten = arr =>
  [].concat(...arr.map(v => (Array.isArray(v) ? deepFlatten(v) : v)))

// 数组打平 至指定深度

const flatten = (arr, depth = 1) =>
  arr.reduce(
    (a, v) =>
      a.concat(depth > 1 && Array.isArray(v) ? flatten(v, depth - 1) : v),
    []
  );

flatten([1, [2], 3, 4]); // [1, 2, 3, 4]
flatten([1, [2, [3, [4, 5], 6], 7], 8], 2); // [1, 2, 3, [4, 5], 6, 7, 8]
  • 利用 map 将多维数组中的值返回成新数组,最后再展开与 [] 连接
  • 可以看到,在解决一些深层次嵌套问题时(深度冻结一个对象),大多会用到递归思想,以后类似问题可以往这方面思考

5、两个数组的交集(Set的使用)

const difference = (a, b) => {
  const s = new Set(b);
  return a.filter(x => !s.has(x));
}
difference([1, 2, 3, 3], [1, 2, 4]); // [3, 3]
  • 补充几个关于 set 的小知识
  • Set 对象允许你存储任何类型的唯一值(只会出现一次),无论是原始值或者是对象引用
  • 同时 set 的原型上提供了几个方法,size()(值的个数),add()(尾部添加),clear()(清除set对象中的所有元素),has()(返回布尔值)...

与数组相关

  • 除了使用 Array.from() 转换外,还可以使用 ... 展开操作符
  • 去重相关

本例中主要使用 has() 方法来判断两数组中的交集

6、实现一个求阶乘的函数

const factorial = n =>
  n < 0
    ? (() => {
        throw new TypeError('Negative numbers are not allowed!');
      })()
    : n <= 1
    ? 1
    : n * factorial(n - 1);

factorial(6); // 720

7、生成一个指定长度数组,包含斐波那契数列

const fibonacci = n =>
  Array.from({ length: n }).reduce(
    (acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i),
    []
  );

fibonacci(6); // [0, 1, 1, 2, 3, 5]
  • 通过 Array.from() 产生一个指定长度数组
  • reduce() ,给定初始值为 [],再使用 concat() 进行连接 acc,同时就做累加了
  • reduce()的好处就是 参数 acc 是上一次调用回调时返回的累积值

8、实现一个从右侧开始的数组遍历

const forEachRight = (arr, callback) =>
  arr
    .slice()
    .reverse()
    .forEach(callback);
forEachRight([1, 2, 3, 4], val => console.log(val)); // '4', '3', '2', '1'
  • 有点意思,从右侧开始遍历,其实就是先拷贝一个副本,然后颠倒,再遍历

9、全屏模式下打开或关闭一个元素

const fullscreen = (mode = true, el = 'body') =>
  mode
    ? document.querySelector(el).requestFullscreen()
    : document.exitFullscreen();

fullscreen(); // Opens `body` in fullscreen mode
fullscreen(false); // Exits fullscreen mode
  • requestFullscreen() 这个倒是是没见过

10、节流函数

const throttle = (fn, wait) => {
  let inThrottle, lastFn, lastTime;
  return function() {
    const context = this,
      args = arguments;
    if (!inThrottle) {
      fn.apply(context, args);
      lastTime = Date.now();
      inThrottle = true;
    } else {
      clearTimeout(lastFn);
      lastFn = setTimeout(function() {
        if (Date.now() - lastTime >= wait) {
          fn.apply(context, args);
          lastTime = Date.now();
        }
      }, Math.max(wait - (Date.now() - lastTime), 0));
    }
  };
};

window.addEventListener(
  'resize',
  throttle(function(evt) {
    console.log(window.innerWidth);
    console.log(window.innerHeight);
  }, 250)
); // Will log the window dimensions at most every 250ms
点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
记录 30 seconds of code 项目个人觉得中有价值的片段或者小技巧(三)
GI系列获取元素距离顶部的距离jsconstgetVerticalOffsetelletoffsetel.offsetTop,elel;while(el.offsetParent)elel.offsetParent;offsetel.offsetTop;returnoffse
记录 30 seconds of code 项目个人觉得中有价值的片段或者小技巧 (一)
AC系列1、号的隐式类型转换使用js3//31,2,3.slice(1)//将3转换为了32、日期的转换jsconstaddDaysToDate(date,n)constdnewDate(date);d.setDate(d.getDate()n);returnd.toISOS
Karen110 Karen110
2年前
一篇文章带你了解JavaScript日期
日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用
Chase620 Chase620
3年前
防抖和节流
防抖触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次触发,则重新计算事件思路每次触发的时候取消之前的延时调用方法,以当下为准//防抖functiondebounce(fn){lettimeoutnull;returnfunction(){clearTimeout
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
记录 30 seconds of code 项目个人觉得中有价值的片段或者小技巧(四)
JZ系列获取数组元素下标(findIndex的实现)jsconstlinearSearch(arr,item)for(constiinarr)if(arriitem)returni;return1;;linearSearch(2,9,9,9);//1linearSearch(
Stella981 Stella981
2年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这