2024年最新前端应该要掌握的几种手写代码实现,必看的70道面试题回答

打开全栈工匠技能包-1小时轻松掌握SSR

两小时精通jq+bs插件开发

生产环境下如歌部署Node.js

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

网易内部VUE自定义插件库NPM集成

谁说前端不用懂安全,XSS跨站脚本的危害

webpack的loader到底是什么样的?两小时带你写一个自己loader

  • 判断类型是否为原始类型,如果是,无需拷贝,直接返回

  • 为避免出现循环引用,拷贝对象时先判断存储空间中是否存在当前对象,如果有就直接返回

  • 开辟一个存储空间,来存储当前对象和拷贝对象的对应关系

  • 对引用类型递归拷贝直到属性为原始类型

const deepClone = (target, cache = new WeakMap()) => {

if(target === null || typeof target !== ‘object’) {

return target

}

if(cache.get(target)) {

return target

}

const copy = Array.isArray(target) ? [] : {}

cache.set(target, copy)

Object.keys(target).forEach(key => copy[key] = deepClone(obj[key], cache))

return copy

}

深拷贝(尤雨溪版)

vuex源码

  • 原理与上一版类似

function find(list, f) {

return list.filter(f)[0]

}

function deepCopy(obj, cache = []) {

// just return if obj is immutable value

if (obj === null || typeof obj !== ‘object’) {

return obj

}

// if obj is hit, it is in circular structure

const hit = find(cache, c => c.original === obj)

if (hit) {

return hit.copy

}

const copy = Array.isArray(obj) ? [] : {}

// put the copy into cache at first

// because we want to refer it in recursive deepCopy

cache.push({

original: obj,

copy

})

Object.keys(obj).forEach(key => copy[key] = deepCopy(obj[key], cache))

return copy

}

函数防抖
  • this继承自父级上下文,指向触发事件的目标元素

  • 事件被触发时,传入event对象

  • 传入leading参数,判断是否可以立即执行回调函数,不必要等到事件停止触发后才开始执行

  • 回调函数可以有返回值,需要返回执行结果

const debounce = (fn, wait = 300, leading = true) => {

let timerId, result

return function(…args) {

timerId && clearTimeout(timerId)

if (leading) {

if (!timerId) result = fn.apply(this, args)

timerId = setTimeout(() => timerId = null, wait)

} else {

timerId = setTimeout(() => result = fn.apply(this, args), wait)

}

return result

}

}

函数节流(定时器)

const throttle = (fn, wait = 300) => {

let timerId

return function(…args) {

if(!timerId) {

timerId = setTimeout(() => {

timerId = null

return result = fn.apply(this, …args)

}, wait)

}

}

}

函数节流(时间戳)

const throttle = (fn, wait = 300) => {

let prev = 0

let result

return function(…args) {

let now = +new Date()

if(now - prev > wait) {

prev = now

return result = fn.apply(this, …args)

}

}

}

函数节流实现方法区别

| 方法 | 使用时间戳 | 使用定时器 |

| — | — | — |

| 开始触发时 | 立刻执行 | n秒后执行 |

| 停止触发后 | 不再执行事件 | 继续执行一次事件 |

数组去重

const uniqBy = (arr, key) => {

return […new Map(arr.map(item) => [item[key], item])).values()]

}

const singers = [

{ id: 1, name: ‘Leslie Cheung’ },

{ id: 1, name: ‘Leslie Cheung’ },

{ id: 2, name: ‘Eason Chan’ },

]

console.log(uniqBy(singers, ‘id’))

// [

// { id: 1, name: ‘Leslie Cheung’ },

// { id: 2, name: ‘Eason Chan’ },

// ]

原理是利用Map的键不可重复

数组扁平化(技巧版)

const flatten = (arr) => arr.toString().split(‘,’).map(item => +item)

数组扁平化

const flatten = (arr, deep = 1) => {

return arr.reduce((cur, next) => {

return Array.isArray(next) && deep > 1 ?

[…cur, …flatten(next, deep - 1)] :

[…cur, next]

},[])

}

函数柯里化

const currying = (fn) {

_curry = (…args) =>

args.length >= fn.length

? fn(…args)
(…newArgs) => _curry(…args, …newArgs)

}

原理是利用闭包把传入参数保存起来,当传入参数的数量足够执行函数时,就开始执行函数

发布订阅EventEmitter

class EventEmitter {

#subs = {}

emit(event, …args) {

if (this.#subs[event] && this.#subs[event].length) {

this.#subs[event].forEach(cb => cb(…args))

}

}

on(event, cb) {

(this.#subs[event] || (this.#subs[event] = [])).push(cb)

}

off(event, offCb) {

if (offCb) {

if (this.#subs[event] && this.#subs[event].length)

this.#subs[event] = this.#subs[event].filter(cb => cb !== offCb)

} else {

this.#subs[event] = []

}

}

}

subsEventEmitter私有属性(最新特性参考阮一峰老师的ECMAScript 6 入门),通过on注册事件,off注销事件,emit触发事件

寄生组合继承

function Super(foo) {

this.foo = foo

}

Super.prototype.printFoo = function() {

console.log(this.foo)

}

function Sub(bar) {

this.bar = bar

Super.call(this)

}

Sub.prototype = Object.create(Super.prototype)

Sub.prototype.constructor = Sub

ES6版继承

最后

推荐一些系统学习的途径和方法。

路线图

每个Web开发人员必备,很权威很齐全的Web开发文档。作为学习辞典使用,可以查询到每个概念、方法、属性的详细解释,注意使用英文关键字搜索。里面的一些 HTML,CSS,HTTP 技术教程也相当不错。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

HTML 和 CSS:

html5知识

css基础知识

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值