精进 JavaScript | 这些手写你都会吗 ?

前言

不知道今年大家有没有感受到来自互联网的“寒气”,至少我是感受到了,面试的时候手写代码时很常见很常见的事情了。有时候没遇到过还真一时半会写不出来,企业招聘的要求也是越来越高,尤其是一些大厂会对 JS 的功底有着更加苛刻的要求,所以学会手写常见的 JS 模块好像已经快变为一个基本技能了,也慢慢变为我们手写 webpack 手写 mini-vue 的一个 coding 基础 了。当然我们也不完全是为了去准备面试而去学习这些常见模块。死磕这些难啃的骨头之后,你会从中学到很多优秀的思想,对你的职业生涯也是很有帮助的。而且阅读代码本身就是一个很好的习惯,读懂并且理解写代码人的思维逻辑更加重要。

本文中涉及到的手写模块,大多数都是从网上的博客、面筋、牛客网以及自己的面试经验借鉴而来的。希望能对你有个帮助。

基础手写

全排列(力扣原题)

要求以数组的形式返回字符串参数的所有排列组合。

注意:

1.字符串参数中的字符无重复且仅包含小写字母
2.返回的排列组合数组不区分顺序

const _permute = string => {const result = []const map = new Map()const dfs = (path) => {if (path.length === string.length) {result.push(path)return}for (let i = 0; i < string.length; i++) {if (map.get(string[i])) continuemap.set(string[i], true)path += string[i]dfs(path)path = path.substring(0, path.length - 1)map.set(string[i], false)}}dfs('')return result
}
console.log(_permute('abc')) // [ 'abc', 'acb', 'bac', 'bca', 'cab', 'cba' ] 

instanceof

  • 如果 target 为基本数据类型直接返回 false
  • 判断 Fn.prototype 是否在 target 的隐式原型链上
const _instanceof = (target, Fn) => {if ((typeof target !== 'object' && typeof target !== 'function') || target === null)return falselet proto = target.__proto__while (true) {if (proto === null) return falseif (proto === Fn.prototype) return trueproto = proto.__proto__}
}
function A() {}
const a = new A()
console.log(_instanceof(a, A)) // true
console.log(_instanceof(1, A)) // false 

Array.prototype.map

  • map 中的 exc 接受三个参数,分别是: 元素值、元素下标和原数组
  • map 返回的是一个新的数组,地址不一样
// 这里不能直接使用箭头函数,否则无法访问到 this
Array.prototype._map = function (exc) {const result = []this.forEach((item, index, arr) => {result[index] = exc(item, index, arr)})return result
}
const a = new Array(2).fill(2)
console.log(a.map((item, index, arr) => item * index + 1)) // [1,3]
console.log(a._map((item, index, arr) => item * index + 1))// [1,3] 

Array.prototype.filter

  • filter 中的 exc 接受三个参数,与map一致,主要实现的是数组的过滤功能,会根据 exc 函数的返回值来判断是否“留下”该值。
  • filter 返回的是一个新的数组,地址不一致。
Array.prototype._filter = function (exc) {const result = []this.forEach((item, index, arr) => {if (exc(item, index, arr)) {result.push(item)}})return result
}
const b = [1, 3, 4, 5, 6, 2, 5, 1, 8, 20]

console.log(b._filter(item => item % 2 === 0)) // [ 4, 6, 2, 8, 20 ] 

Array.prototype.reduce

  • reduce 接受两个参数,第一个为 exc 函数,第二个为初始值,如果不传默认为 0
  • reduce 最终会返回一个值,当然不一定是 Number 类型的,取决于你是怎么计算的,每次的计算结果都会作为下次 exc 中的第一个参数
Array.prototype._reduce = function (exc, initial = 0) {let result = initialthis.forEach((item) => {result = exc(result, item)})return result
}
console.log(b.reduce((pre, cur) => pre + cur, 0)) // 55
console.log(b._reduce((pre, cur) => pre + cur, 0)) // 55 

Object.create

MDN Object.create() 方法用于创建一个新对象,使用现有的对象来作为新创建对象的原型(prototype)。

Object.prototype._create = function (proto) {const Fn = function () { }Fn.prototype = protoreturn new Fn()
}
function A() { }
const obj = Object.create(A)
const obj2 = Object._create(A)
console.log(obj.__proto__ === A) /
  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值