js - 手写部分原生函数

ru shui 2021-09-21 Javascript
  • Javascript
  • Override
About 1 min

# typeof

// Object.prototype.toString.call(v) === [object Xxxx]
const typeOf = (v: any) => {
  return Object.prototype.toString.call(v).slice(8, -1).toLowerCase()
}
1
2
3
4

# 数组去重

const unique = (arr: any[]) => Array.from(new Set(arr))
const unique2 = (arr: any[]) =>
  arr.filter((item, index) => {
    for (var i = index + 1; i < arr.length; i++) {
      if (item === arr[i]) {
        return false
      }
    }
    return true
  })
1
2
3
4
5
6
7
8
9
10

# 数组扁平化

// 深度优先
function flatten(arr: any[]) {
  return arr.reduce(
    (prev, curr) => prev.concat(Array.isArray(curr) ? flatten(curr) : curr),
    [],
  )
}

// 广度优先,需要借助队列
function flatten2(arr: any[]) {
  let result = []
  let queue: any[][] = [arr]
  while (queue.length) {
    const task = queue.shift()
    for (let i = 0; i < task.length; i++) {
      if (Array.isArray(task[i])) {
        queue.push(task[i])
      } else {
        result.push(task[i])
      }
    }
  }

  return result
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 拷贝

# 浅拷贝

function shallowCopy(v: any) {
  if (typeof v !== 'object') {
    return v
  }
  const keys = Reflect.ownKeys(v)
  const result = Array.isArray(v) ? [] : {}
  for (const key of keys) {
    result[key] = v[key]
  }
  return result
}
1
2
3
4
5
6
7
8
9
10
11

# 深拷贝

const isPlainObject = (v: any) => typeof v === 'object' && v !== null

// 深度优先 + 递归
const map = new Map()
function deepCopy(v: any) {
  if (!isPlainObject(v)) {
    return v
  }

  const keys = Object.keys(v)
  const result = Array.isArray(v) ? [] : {}
  map.set(v, result)
  for (const key of keys) {
    // result[key] = isPlainObject(v[key]) ? deepCopy(v[key]) : v[key]
    if (isPlainObject(v[key])) {
      let copy = map.get(v[key])
      if (copy) {
        result[key] = copy
      } else {
        copy = deepCopy(v[key])
        map.set(v[key], copy)
        result[key] = copy
      }
    } else {
      result[key] = v[key]
    }
  }
  return result
}

// 广度优先 + 非递归。
const map2 = new Map()
function deepCopy2(v: any) {
  if (!isPlainObject(v)) {
    return v
  }

  const result = Array.isArray(v) ? [] : {}
  map2.set(v, result)
  const queue: any[][] = [[v, result]]

  while (queue.length) {
    const [origin, target] = queue.shift()
    const keys = Object.keys(origin)
    for (const key of keys) {
      if (!isPlainObject(origin[key])) {
        target[key] = origin[key]
      } else {
        const copy = map2.get(origin[key])
        if (copy) {
          target[key] = copy
        } else {
          target[key] = Array.isArray(origin[key]) ? [] : {}
          queue.push([origin[key], target[key]])
        }
      }
    }
  }

  return result
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

# instanceof

function isObject(o) {
  return (o !== null && typeof o === 'object') || typeof o === 'function'
}
function instanceOf(left: any, right: any) {
  if (!isObject(left) || !isObject(right)) {
    return false
  }

  let proto = left.__proto__
  while (proto !== null) {
    if (proto === right.prototype) {
      return true
    }
    proto = proto.__proto__
  }
  return false
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Last update: September 21, 2021 17:49
Contributors: Laishuxin