构建前端知识体系 —— 手写代码篇

目录

JavaScript 必写

  • 数组排序(多种方法)
  • 数组去重(多种方法)
  • 数组扁平化
  • 将数组扁平化并去除其中重复数据,最终得到一个升序且不重复的数组
  • 深拷贝
  • 函数防抖节流
  • 实现函数原型方法 call apply bind
  • 实现数组原型方法 forEach map filter some reduce
  • 实现 Promise
  • 实现 Promise.all
  • 实现 Promise.allSettled
  • 封装事件类 EventEmitter(发布订阅模式)

JavaScript 编码能力

  • 函数柯里化
  • 函数记忆
  • 对象比较
  • 计算字符串中出现最多的字母与出现次数
  • 实现一个 trim 方法
  • js 实现一个函数 获得 url 参数的值
  • 驼峰转下划线:appleOrangePinkBoy => apple_orange_pink_boy
  • 实现一个 get 方法通过.来取对象的值
  • 封装一下 axios 或者手写封装 ajax
  • 实现一个 once 函数,传入函数参数只执行一次
  • 实现一个简单的模板字符串替换
  • 合并对象 merge
  • 求多个数组之间的交集
  • 实现一个版本比较方法 compareVersion

JavaScript 必写

数组排序(多种方法)

// 冒泡排序
// 冒泡排序的原理如下:
// 从第一个元素开始,把当前元素和下一个元素进行比较。如果当前元素大,那么就交换位置,重复操作直到比较到最后一个元素,那么此时(一轮结束后)最后一个元素就是该数组中最大的数
// 下一轮重复以上操作,但是此时最后一个元素已经是最大数了,所以不需要再比较最后一个元素,只需要比较到 length - 1 -i的位置
function bubble(array) {for (let i = 0; i < array.length - 1; i++) {console.log('第' + (i + 1) + '轮开始')let flag = true// 从 0 到 `length - 1` 遍历for (let j = 0; j < array.length - 1 - i; j++) {if (array[j] > array[j + 1]) {flag = false;[array[j], array[j + 1]] = [array[j + 1], array[j]]console.log('第' + (j + 1) + '次:' + array.toString(array))}}if (flag) {console.log('第' + (i + 1) + '轮后数据结束变化更新')break}}return array
}

console.log(bubble([3, 2, 1, 4, 8, 6, 7]))
// 第1轮开始
// 第1次:2,3,1,4,8,6,7
// 第2次:2,1,3,4,8,6,7
// 第5次:2,1,3,4,6,8,7
// 第6次:2,1,3,4,6,7,8
// 第2轮开始
// 第1次:1,2,3,4,6,7,8
// 第3轮开始
// 第3轮后数据结束变化更新

// 时间复杂度是 O(n * n) 
// http://www.ruanyifeng.com/blog/2011/04/quicksort_in_javascript.html
// 快排
// 快排的原理如下:
//第一步,选择中间的元素作为"基准"。(基准值可以任意选择,但是选择中间的值比较容易理解。)
//第二步,按照顺序,将每个元素与"基准"进行比较,形成两个子集,一个"小于基准",另一个"大于基准"。
//第三步,对两个子集不断重复第一步和第二步,直到所有子集只剩下一个元素为止。
function quickSort(arr) {if (arr.length <= 1) {return arr //递归出⼝}var pivotIndex = Math.floor(arr.length / 2)// 取出基准值var pivot = arr.splice(pivotIndex, 1)var left = []var right = []for (var i = 0; i < arr.length; i++) {if (arr[i] < pivot) {left.push(arr[i])} else {right.push(arr[i])}}return quickSort(left).concat(pivot, quickSort(right))
}
// 该算法的复杂度和归并排序是相同的,但是额外空间复杂度比归并排序少,只需 O(logN),并且相比归并排序来说,所需的常数时间也更少。
console.log(quickSort([3, 2, 1, 4, 8, 6, 7])) 
// 原地快排
function quickSort(arr, low = 0, high = arr.length - 1) {if (low >= high) returnlet left = lowlet right = highlet flag = arr[left]// 判断左右游标是否重合,如果重合,循环结束while (left < right) {// 右边大,继续向左比较if (flag <= arr[right]) {right--}// 交换下一个可能不合理的位置arr[left] = arr[right]// 左边大,继续向右比较if (flag >= arr[left]) {left++}// 交换下一个arr[right] = arr[left]}//重合之后,交换基准数arr[left] = flagquickSort(arr, low, left - 1)quickSort(arr, left + 1, high)return arr
}
console.log(quickSort([4, 3, 8, 1, 9, 6, 2])) 

数组去重(多种方法)

//github.com/mqyqingfeng/Blog/issues/27

var array = [1, 2, 1, 1, '1']

;(() => {var unique = a => [...new Set(a)]console.log(unique(array)) // [1, 2, "1"]
})()
;(() => {function unique(array) {var res = []for (var i = 0, len = array.length; i < len; i++) {var current = array[i]if (res.indexOf(current) === -1) {res.push(current)}}return res}console.log(unique(array)) // [1, 2, "1"]
})()
;(() => {function unique(array) {var res = []for (var i = 0, len = array.length; i < len; i++) {var current = array[i]if (res.indexOf(current) === -1) {res.push(current)}}return res}console.log(unique(array)) // [1, 2, "1"]
})()
;(() => {function unique(array) {var res = array.filter(function(item, index, array) {//若当前元素所在的索引位置 === 在原始数组中出现该值的的第一个索引,则 true 返回当前元素return array.indexOf(item) === index})return res}console.log(unique(array))
})()
;(() => {function unique(array) {var o = new Map()// set 设置后返回新的 Map 对象return array.filter(key => !o.has(key) && o.set(key, true))}console.log(unique(array))
})() 

数组扁平化

let entry = [[1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10]

// 实现 Array.prototype.flat()
// https://github.com/mqyqingfeng/Blog/issues/36

;(() => {function flatten(arr) {let res = []for (let i = 0; i < arr.length; i++) {let item = arr[i]if (Array.isArray(item)) {res = res.concat(flatten(item))} else {res.concat(item)}}return res}console.log(flatten(arr)) // [1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12, 13, 14, 10]
})()
;(() => {function flatten(arr) {return arr.reduce((prev, curr) => {return prev.concat(Array.isArray(curr) ? flatten(curr) : curr)}, [])}console.log(flatten(arr))
})()
;(() => {function flatten(arr) {while (arr.some(item => Array.isArray(item))) {arr = [].concat(...arr)}return arr}console.log(flatten(arr))
})() 

ES6 增加了扩展运算符,用于取出参数对象的所有可遍历属性,拷贝到当前对象之中:

var arr = [1, [2, [3, 4]]]
console.log([].concat(...arr)) // [1, 2, [3, 4]] 

将数组扁平化并去除其中重复数据,最终得到一个升序且不重复的数组

Array.prototype.flat = function() {return [].concat(...this.map(item => (Array.isArray(item) ? item.flat() : [item])))
}

Array.prototype.unique = function() {return [...new Set(this)]
}

const sort = (a, b) => a - b

console.log(arr.flat().unique().sort(sort)
) // [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 ] 

深拷贝

用 JSON,存在如下缺点:

  • 不支持 Date、正则、undefined、函数等数据
  • 不支持引用(即环状结构)
const deepClone = o => JSON.parse(JSON.stringify(o)) 

基础版(新增函数函数类型支持),推荐使用 lodash 的深拷贝函数

function deepCopy(target) {if (typeof target == 'object') {const result = Array.isArray(target) ? [] : {}for (const key in target) {if (typeof target[key]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值