# 30s理解一些常用JS代码片段

Short code snippets for all your development needs

30 seconds of code (opens new window)

# promise柯里化

const promisify = func => (...args) =>
  new Promise((resolve, reject) =>
    func(...args, (err, result) => (err ? reject(err) : resolve(result)))
  )

const delay = promisify((d, cb) => setTimeout(cb, d))
delay(1000).then(() => console.log('promisify')) // 1s后输出promisify  
1
2
3
4
5
6
7

# deepFlatten 深度平铺数组

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

deepFlatten([1, [2], [[3], 4], 5]) // [1, 2, 3, 4, 5]
1
2
3

# flatten 平铺数组

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

flatten([1, [2], [[3], 4], 5]) // [1, 2, [3], 4, 5]
flatten([1, [2], [[3], 4], 5], 2) // [1, 2, 3, 4, 5]
1
2
3
4
5
6
7

# distinctValuesOfArray 数组去重

const distinctValuesOfArray = arr => [...new Set(arr)]
// or
const distinctValuesOfArray = arr => Array.from(new Set(arr))

distinctValuesOfArray([1, 1, 2, 3]) // [1, 2, 3]
1
2
3
4
5

# groupBy 数组分组

const groupBy = (arr, fn) =>
  arr.map(typeof fn === 'function' ? fn : val => val[fn]).reduce((acc, val, i) => {
    acc[val] = (acc[val] || []).concat(arr[i])
    return acc
  }, {})

groupBy([6.1, 4.2, 6.3], Math.floor) // {4: [4], 6: [6.1, 6.3]}
1
2
3
4
5
6
7

# set操作

  • 数组并集
const union = (a, b) => Array.from(new Set([...a, ...b]))
1
  • 数组交集
const intersection = (a, b) => {
  const s = new Set(b)
  return a.filter(x => s.has(x))
}
const similarity = (a, b) => a.filter(v => b.includes(v))
1
2
3
4
5
  • 数组差集
const difference = (a, b) => {
  const s = new Set(b)
  return a.filter(x => !s.has(x))
}
1
2
3
4
let a = [1, 2, 3]
let b = [2, 3, 4]
union(a, b) // [1, 2, 3, 4]
intersection(a, b) // [2, 3]
difference(a, b) // [1]
1
2
3
4
5

# shuffle 随机排序数组

const shuffle = ([...arr]) => {
  let m = arr.length;
  while (m) {
    const i = Math.floor(Math.random() * m--);
    [arr[m], arr[i]] = [arr[i], arr[m]];
  }
  return arr;
};

shuffle([7, 4, 18, 2, 3, 6])
1
2
3
4
5
6
7
8
9
10

# scroll2Top 回到顶部

const scrollToTop = () => {
  const c = document.documentElement.scrollTop || document.body.scrollTop;
  if (c > 0) {
    window.requestAnimationFrame(scrollToTop);
    window.scrollTo(0, c - c / 8);
  }
};
1
2
3
4
5
6
7

# indexOf 比较简化

利用位运算符 ~,对结果取反操作

~-1 // -( -1 + 1 ) = 0
~0 // -( 0 + 1 ) = -1
~1 // -( 1 + 1 ) = -2
1
2
3

一般indexOf判断值是否存在都是与-1做比较,于是可以简化如下判断:

const arr = [1, 2, 3]
// 存在,等效于 > -1
~arr.indexOf(1) // -1
!!~arr.indexOf(1) // true

// 不存在,等效于 === -1
!~arr.indexOf(1)
1
2
3
4
5
6
7

# initializeArrayWithRange 初始化特定范围数组

包含 end 就加+1

const initializeArrayWithRange = (end, start = 0, step = 1) =>
  Array.from({ length: Math.ceil((end + 1 - start) / step) })
  .map((v, i) => i * step + start)
1
2
3