千锋教育-做有情怀、有良心、有品质的职业教育机构

400-811-9990
手机站
千锋教育

千锋学习站 | 随时随地免费学

千锋教育

扫一扫进入千锋手机站

领取全套视频
千锋教育

关注千锋学习站小程序
随时随地免费学习课程

上海
  • 北京
  • 郑州
  • 武汉
  • 成都
  • 西安
  • 沈阳
  • 广州
  • 南京
  • 深圳
  • 大连
  • 青岛
  • 杭州
  • 重庆
当前位置:沈阳千锋IT培训  >  技术干货  >  20个实用的JavaScript代码片段,助你成为更好的开发者

20个实用的JavaScript代码片段,助你成为更好的开发者

来源:千锋教育
发布人:qyf
时间: 2022-11-24 17:35:26

  开发人员每天面临的几乎所有问题都可以通过解决一组较小的问题来解决,针对单个明确定义的问题的小解决方案。这些解决方案可以最好地描述为“纯函数”。

  尽管这些函数中的大多数是在不同的库中实现的,但重要的是要了解如何以及何时将困难的问题分解为更小的问题。这种解决问题的思维方式将提高我们的开发效率,并使我们成为更好的开发人员。

  今天的文章中,我分享的是我经常用来解决各种问题的 20 个有用的“纯函数”的无序集合,希望对你也有用。

  下面,我们开始吧。

20个实用的JavaScript代码片段

  01、GetValue

  给定一个对象或数组,函数将返回指定路径的值,否则为 null。

  const getValue = (obj, path) => path

  .replace(/\[([^[\]]*)]/g, '.$1.')

  .split('.')

  .filter(prop => prop !== '')

  .reduce((prev, next) => (

  prev instanceof Object ? prev[next] : undefined

  ), obj);

  

  getValue({ a: { b: c: 'd' } }, 'a.b.c'); // = d

  getValue({ a: { b: c: [1. 2] } }, 'a.b.c[1]'); // = 2

  02、Clamp

  确保值在指定范围内,否则“clamp”到最接近的最小值和最大值。

  const clamp = (min, max, value) => {

  if (min > max) throw new Error('min cannot be greater than max');

  return value < min

  ? min

  : value > max

  ? max

  : value;

  }

  }

  

  clamp(0. 10. -5); // = 0

  clamp(0. 10. 20); // = 10

  03、Sleep

  在执行下一个操作之前等待指定的持续时间(以毫秒为单位)。

  const sleep = async (duration) => (

  new Promise(resolve =>

  setTimeout(resolve, duration)

  )

  );

  04、GroupBy

  根据键控功能对对象中的相关项进行分组和索引。

  const groupBy = (fn, list) => (

  list.reduce((prev, next) => ({

  ...prev,

  [fn(next)]: [...(prev[fn(next)] || []), next]

  }), {})

  );

  groupBy(vehicle => vehicle.make, [

  { make: 'tesla', model: '3' },

  { make: 'tesla', model: 'y' },

  { make: 'ford', model: 'mach-e' },

  ]);  

  // {

  //   tesla: [ { make: 'tesla', ... }, { make: 'tesla', ... } ],

  //   ford: [ { make: 'ford', ... } ],

  // }

  05、Collect By

  根据键控功能创建包含相关项目的子列表。

  import groupBy from './groupBy';

  const collectBy = (fn, list) =>

  Object.values(groupBy(fn, list));

  collectBy(vehicle => vehicle.make, [

  { make: 'tesla', model: '3' },

  { make: 'tesla', model: 'y' },

  { make: 'ford', model: 'mach-e' },

  ]);

  // [

  //   [ { make: 'tesla', ... }, { make: 'tesla', ... } ],

  //   [ { make: 'ford', ... } ],

  // ]

  06、Head

  获取列表的第一个元素。这个函数对于编写干净易读的代码很有用。

  const head = list => list[0];

  head([1. 2. 3]); // = 1

  head([]); // = undefined

  07、Tail

  获取列表中除第一个元素之外的所有元素。这个函数对于编写干净易读的代码很有用。

  const tail = list => list.slice(1);

  tail([1. 2. 3]); // = [2. 3]

  tail([]); // = []

  08、Flatten

  通过递归地从嵌套子列表中提取所有项目来创建一个平面列表。

  const flatten = list => list.reduce((prev, next) => ([

  ...prev,

  ...(Array.isArray(next) ? flatten(next) : [next])

  ]), []);

  flatten([[1. 2. [3. 4], 5. [6. [7. 8]]]]); // = [1. 2. 3. 4. 5. 6. 7. 8]

  09、Intersection By

  查找键控函数定义的两个列表中存在的所有值。

  const intersectionBy = (fn, listA, listB) => {

  const b = new Set(listB.map(fn);

  return listA.filter(val => b.has(fn(val)));

  };  

  intersectionBy(v => v, [1. 2. 3], [2. 3. 4]); // = [2. 3]

  intersectionBy(v => v, [{ a: 1 }, { a: 2 }], [{ a: 2}, { a: 3 }, { a: 4 }]); // = [{ a: 2 }];

  10、IndexBy

  通过键控函数确定的值对列表中的每个元素进行索引。

  const indexBy = (fn, list) =>

  list.reduce((prev, next) => ({

  ...prev,

  [fn(next)]: next

  }, {});

  indexBy(val => val.a, [{ a: 1 }, { a: 2 }, { a: 3 }]);

  // = { 1: { a: 1 }, 2: { a:2 }, 3: { a: 3 } }

  11、DifferenceBy

  查找第一个列表中不存在于第二个列表中的所有项目,由键控功能确定。

  import indexBy from './indexBy';

  const differenceBy = (fn, listA, listB) => {

  const bIndex = indexBy(fn, listb);

  return listA.filter(val => !bIndex[fn(val)]);

  });

  differenceBy(val => val, [1.2.3], [3.4.5]); // = [1.2]

  differenceBy(

  vehicle => vehicle.make,

  [{ make: 'tesla' }, { make: 'ford' }, { make: 'gm' }],

  [{ make: 'tesla' }, { make: 'bmw' }, { make: 'audi' }],

  ); // = [{ make: 'ford' }, { make: 'gm' }]

  12、Recover With

  如果给定函数抛出错误,则返回默认值。

  const recoverWith = async (defaultValue, fn, ...args) => {

  try {

  const result = await fn(...args);

  return result;

  } catch (_e) {

  return defaultValue;

  }

  }

  recoverWith('A', val => val, 'B'); // = B

  recoverWith('A', () => { throw new Error() }); // = 'A'

  13、Distance

  计算两点 p1 和 p2 之间的距离。

  const distance = ([x0. y0], [x1. y1]) => (

  Math.hypot(x1 - x0. y1 - y0)

  );  distance([0. 1], [5. 4]); // = 5.8309518948453

  14、Drop While

  从列表中删除元素,从第一个元素开始,直到满足 som 谓词。

  const dropWhile = (pred, list) => {

  let index = 0;

  list.every(elem => {

  index++;

  return pred(elem);

  });

  return list.slice(index-1);

  }

  

  dropWhile(val => (val < 5), [1.2.3.4.5.6.7]); // = [5.6.7]

  15、Sum By

  给定一些产生每个元素的单独值的函数,计算列表中所有元素的总和。

  const sumBy = (fn, list) =>

  list.reduce((prev, next) => prev + fn(next), 0);

  sumBy(product => product.price, [

  { name: 'pizza', price: 10 },

  { name: 'pepsi', price: 5 },

  { name: 'salad', price: 5 },

  ]); // = 20

  16、升序

  给定一个评估函数,创建一个升序比较器函数。

  const ascending = (fn) => (a, b) => {

  const valA = fn(a);

  const valB = fn(b);

  return valA < valB ? -1 : valA > valB ? 1 : 0;

  }

  const byPrice = ascending(val => val.price);

  [{ price: 300 }, { price: 100 }, { price: 200 }].sort(byPrice);

  // = [{ price: 100 }, { price: 200 }, { price: 300 }]

  17、降序

  给定一个评估函数,创建一个降序比较器函数。

  const descending = (fn) => (a, b) => {

  const valA = fn(b);

  const valB = fn(a);

  return valA < valB ? -1 : valA > valB ? 1 : 0;

  }

  const byPrice = descending(val => val.price);

  [{ price: 300 }, { price: 100 }, { price: 200 }].sort(byPrice);

  // = [{ price: 300 }, { price: 200 }, { price: 100 }]

  18、Find Key

  在满足给定predicate的索引中找到第一个键值。

  const findKey = (predicate, index) => Object

  .keys(index)

  .find(key => predicate(index[key], key, index));

  findKey(

  car => !car.available,

  {

  tesla: { available: true },

  ford: { available: false },

  gm: { available: true }

  },

  ); // = "ford"

  19、Bifurcate By

  将给定列表的值拆分为两个列表,一个包含predicate函数评估为真值的值,另一个包含假值。

  const bifurcateBy = (predicate, list) =>

  list.reduce((acc, val, i) => (

  acc[predicate(val, i) ? 0 : 1].push(val), acc),

  [[], []]

  );  

  bifurcateBy(val => val > 0. [-1. 2. -3. 4]);

  // = [[2. 4], [-1. -3]]

  20、Pipe

  执行从左到右的功能组合。所有额外的参数都将传递给列表中的第一个函数,因此可以有任何数量。结果将在第二个传递,第二个的结果将传递给第三个,……以此类推,直到处理完所有函数。

  const pipe = (functions, ...args) => (

  functions.reduce(

  (prev, next) => Array.isArray(prev) ? next(...prev) : next(prev),

  args

  )

  );

  pipe([Math.abs, Math.floor, val => -val], 4.20); // = -4

  pipe([(a, b) => a - b, Math.abs], 5. 10); // = 5

  最后的想法

  尽管所有这些功能对于帮助我们解决正在处理的问题非常有用,但最重要的是,我们要知道如何将复杂困难的问题进行分解,这样就可以独立解决每个明确的小问题。一旦你掌握了这个解决问题的小技巧,那么你已经在成为一名优秀的开发者的路上了!

声明:本站稿件版权均属千锋教育所有,未经许可不得擅自转载。

10年以上业内强师集结,手把手带你蜕变精英

请您保持通讯畅通,专属学习老师24小时内将与您1V1沟通

免费领取

今日已有369人领取成功

刘同学 138****2860 刚刚成功领取
王同学 131****2015 刚刚成功领取
张同学 133****4652 刚刚成功领取
李同学 135****8607 刚刚成功领取
杨同学 132****5667 刚刚成功领取
岳同学 134****6652 刚刚成功领取
梁同学 157****2950 刚刚成功领取
刘同学 189****1015 刚刚成功领取
张同学 155****4678 刚刚成功领取
邹同学 139****2907 刚刚成功领取
董同学 138****2867 刚刚成功领取
周同学 136****3602 刚刚成功领取

猜你喜欢LIKE

抖音流量池到底是什么概念?

2022-11-25

直播间场景的重要性以及有什么影响?

2022-11-25

表单的数据采集和提交

2022-11-24

最新文章NEW

小店体验分越来越低,该如何提升分数?

2022-11-28

为什么开播的时候在线人数很高,随着直播时长越往后在线人数越少?

2022-11-25

新号在线人数稳定一段时间后,为什么最近在线人数突然就掉到很少了?

2022-11-25

相关推荐HOT

更多>>

快速通道 更多>>

最新开班信息 更多>>

网友热搜 更多>>