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

请叫我海龟先生
• 阅读 1064

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
点赞
收藏
评论区
推荐文章
秃头王路飞 秃头王路飞
6天前
webpack5手撸vue2脚手架
webpack5手撸vue相信工作个12年的小伙伴们在面试的时候多多少少怕被问到关于webpack方面的知识,本菜鸟最近闲来无事,就尝试了手撸了下vue2的脚手架,第一次发帖实在是没有经验,望海涵。 language JavaScript "name": "vuecliversion2", "version": "1.0.0", "desc
Jacquelyn38 Jacquelyn38
1年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。 1、使用解构获取json数据let jsonData   id: 1, status: "OK", data: ['a', 'b'] ; let  id, status, data: number   jsonData; console.log(id, status, number )
blmius blmius
1年前
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:SQL Mode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。 全局s
小森森 小森森
6天前
校园表白墙微信小程序V1.0 SayLove -基于微信云开发-一键快速搭建,开箱即用
后续会继续更新,敬请期待2.0全新版本 欢迎添加左边的微信一起探讨!项目地址:](https://www.aliyun.com/activity/daily/bestoffer?userCodesskuuw5n) \2. Bug修复更新日历 2. 情侣脸功能大家不要使用了,现在阿里云的接口已经要收费了(土豪请随意), \ \ 和 注意
Karen110 Karen110
1年前
一篇文章带你了解JavaScript日期
日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:Thu Feb 02 2019 09:59:51 GMT+0800 (中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。 1\. 显示日期使用
Wesley13 Wesley13
11个月前
JS中有趣的知识
1.分号与换行 function fn1(){ return { name: 'javascript' }; } function fn2(){ return { name: 'javascript'
Stella981 Stella981
11个月前
Android So动态加载 优雅实现与原理分析
> 背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载. ![](https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png) 点击上方“蓝字”关注我
Stella981 Stella981
11个月前
Angular material mat
Icon Icon Name mat-icon code _add\_comment_ add comment icon <mat-icon> add\_comment</mat-icon> _attach\_file_ attach file icon <mat-icon> attach\_file</mat-icon> _attach\
Wesley13 Wesley13
11个月前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
#### 背景描述 # Time: 2019-01-24T00:08:14.705724+08:00 # User@Host: **[**] @ [**] Id: ** # Schema: sentrymeta Last_errno: 0 Killed: 0 # Query_time: 0.315758 Lock_
helloworld_34035044 helloworld_34035044
2个月前
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。 uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid() 或 uuid(sep)参数说明:sep 布尔值,生成的uuid中是否包含分隔符'',缺省为