手撕前端面试代码题

深度优先实现

`function combine(str) {//记录已经使用过的字符,深度优先访问所有方案

let result=[]

;(function _combine(str,path=‘’){

if (str.length===0) return result.push(path)

for (let i in str) {

_combine(str.slice(0,i)+str.slice((+i)+1,str.length),path+str[i])

}

})(str)

//可能会出现类似"aa"=>[aa,aa,aa,aa]的情况,需要去重

return […new Set(result)]

}`

排序和查找


插入排序

`function sort(arr) {//原地

for (let i in arr) {//选一个元素

while (i>0&&arr[i]<arr[i-1]) {//向前移动到合适的位置

[arr[i],arr[i-1]]=[arr[i-1],arr[i]]

i–

}

}

}`

归并排序

`function sort(arr) {

if (arr.length===1) return arr

//分成两部分

let mid=Math.floor(arr.length/2)

let [part1,part2]=[sort(arr.slice(0,mid)),sort(arr.slice(mid))]

//对比+合并

let result=[]

while (part1.length>0&&part2.length>0)

result.push((part1[0]<part2[0]?part1:part2).shift())

return […result,…part1,…part2]

}`

快速排序

`function sort(arr) {

if (arr.length<=1) return arr

//选基准值

let mid_pos=arr.length>>1

let mid=arr.splice(mid_pos,1)[0]

let left=[],right=[]

//和基准值比较,分别插入left,right数组

arr.forEach(item=>(item<=mid?left:right).push(item))

return […sort(left),mid,…sort(right)]//递归调用排序

}`

二分查找

`function search(arr,target) {//循环写法,不断移动左右指针,缩小范围

let left=0,right=arr.length-1

while (left<=right) {

const mid_pos=Math.floor((left+right)/2)

const mid_val=arr[mid_pos]

if (target===mid_val) {

return mid_pos

} else if (target>mid_val) {

left=mid_pos+1

} else {

right=mid_pos-1

}

}

return -1

}`

找出出现次数最多的元素 - getMostItem()

`function getMost(arr) {

//计数

let map=new Map()

arr.forEach(item=>{

if (map.has(item)) {

map.set(item,map.get(item)+1)

} else {

map.set(item,1)

}

})

//找出出现最多

let [max_vals,max_num]=[[arr[0]],map.get(arr[0])]

map.forEach((count,item)=>{

if (count>max_num){

max_vals=[item]

max_num=count

} else {

max_vals.push(item)

}

})

return max_vals

}

console.log(getMost([‘1’, ‘2’, ‘3’, ‘3’, ‘55’, ‘3’, ‘55’, ‘55’]))`

功能函数实现


setTimeout实现setInterval

`function myInterval(fn,interval,…args) {

let context=this

setTimeout(()=>{

fn.apply(context,args)

myInterval(fn,interval,…args)//别忘了为它传入参数

},interval)

}

myInterval((num)=>console.log(num),500,10)`

函数柯里化

`function sum(…args1){

return function (…args2) {

return […args1,…args2].reduce((p,n)=>p+n)

}

}

console.log(sum(1, 2, 2)(7))`

防抖 节流

实现了两个加工方法,返回一个加工后的防抖/节流函数

防抖

`function debounce(fn,delay) {

let timer=null

return function (){

if (timer) clearTimeout(timer)

timer=setTimeout(()=>fn.call(…arguments),delay)//别忘了为它传入参数

}

}`

节流

`function throttle(fn,delay) {

let flag=true

return function() {

if (!flag) return

flag=false

setTimeout(()=>{

fn(…arguments)//别忘了为它传入参数

flag=true

},delay)

}

}`

数据结构


单链表

`function Node(element) {//结点类

[this.element,this.next]=[element,null]

}

class LinkList {//链表类

constructor() {

this.length=0

this.head=new Node()

this.tail=new Node()

this.head.next=this.tail

}

get_all() {

let result=[]

let now=this.head

while (now.next!==this.tail) {

now=now.next

result.push(now.element)

}

return result

}

unshift(element) {//开头添加

let node=new Node(element)

node.next=this.head.next

this.head.next=node

}

shift(){//开头删除

let node=this.head.next

this.head.next=this.head.next.next

return node.element

}

}

let list=new LinkList()

list.unshift(15)

list.unshift(16)

list.unshift(17)

console.log(list.shift())//17

console.log(list.get_all())//[ 16, 15 ]`

设计模式


发布订阅模式

`class Observer {

constructor() {

this.events={}//事件中心

}

publish(eventName,…args) {//发布=>调用事件中心中对应的函数

if (this.events[eventName])

this.events[eventName].forEach(cb=>cb.apply(this,args))

}

subscribe(eventName,callback) {//订阅=>向事件中心中添加事件

if (this.events[eventName]) {

this.events[eventName].push(callback)

} else {

this.events[eventName]=[callback]

}

}

unSubscribe(eventName,callback) {//取消订阅

if (events[eventName])

events[eventName]=events[eventName].filter(cb=>cb!==callback)

}

}`

JS原生API实现


bind() call() apply()

apply()

`Function.prototype.myApply=function(context,args) {

context.fn=this//为context设置函数属性

let result=context.fn(…args)//调用函数

delete context.fn//删除context的函数属性

return result

}`

call()

`//除了…args

//和apply都一样

Function.prototype.myCall=function(context,…args) {

context.fn=this

let result=context.fn(…args)

delete context.fn

return result

}`

bind()

`Function.prototype.myBind=function(context,args1) {//使用[闭包+apply]实现

return (…args2)=>this.apply(context,[…args1,…args2]);

}`

InstanceOf

`function myInstanceOf(son,father) {//沿着父亲的原型链向上查找是否有儿子的原型

while (true) {

son=son.proto

if (!son) return false

if (son===father.prototype) return true

}

}

myInstanceOf([], Array)  // true`

new

`function myNew(constructor_fn,…args) {

//构造新的空对象

let new_obj={}

new_obj.proto=constructor_fn.prototype

let result=constructor_fn.apply(new_obj,args)

//如果构造函数没有返回一个对象,则返回新创建的对象

//如果构造函数返回了一个对象,则返回那个对象

//如果构造函数返回原始值,则当作没有返回对象

return result instanceof Object?result:new_obj

}

function Animal(name) {

this.name = name;

}

let animal = myNew(Animal, ‘dog’);

console.log(animal.name)  // dog`

reduce() forEach()

reduce()

api用法:

arr.reduce(function(prev, cur, index, arr){}, initialValue)

实现:

`Array.prototype.myReduce=function(fn,init_val){

let [val,idx]=init_val?[init_val,0]:[this[0],1]//设置初始值

for (let i=idx,len=this.length;i<len;i++) {

val=fn(val,this[i],i,this)//循环并迭代结果

}

return val

}

console.log([1,2,3,4,5].reduce((pre,item)=>pre+item,0)) // 15`

forEach()

api用法:

`[1,3,5,7,9].myForEach(function(item,index,arr) {

console.log(this)

},15)`

实现:

`Array.prototype.myForEach=function(fn,temp_this) {

for (let i=0,len=this.length;i<len;i++){

fn.call(temp_this,this[i],i,this)//循环数组元素,为回调函数传入参数

}

}`

Promise

Promise.all()

`Promise.prototype.all=function(promiseList) {

return new Promise((resolve,reject)=>{

if (promiseList.length===0) return resolve([])

let result=[],count=0

promiseList.forEach((promise,index)=>{

Promise.resolve(promise).then(value=>{

result[index]=value

if (++count===promiseList.length) resolve(result)

},reason=>reject(reason))

})

})

}`

ES6所有API完整实现

通过Promise/A+ test测试

实现细节过多,还请参照Promise/A+规范阅读

也可以直接参考我关于promise的笔记

深入理解promise

https://blog.csdn.net/weixin_43758603/article/details/109641486

`class Promise {

constructor(task) {

this.status=“pending”

this.value=undefined

this.reason=undefined

this.fulfilled_callbacks=[]

this.rejected_callbacks=[]

try {

task(this._resolve,this._reject)

} catch (error) {

this._reject(error)

}

}

then(onFulfilled,onRejected){

if (this.status===‘fulfilled’) {

let promise2=new Promise((resolve,reject)=>{

setTimeout(()=>{

try {

if (!this._isFunction(onFulfilled)) {

resolve(this.value)

} else {

this._resolvePromise(promise2,onFulfilled(this.value))

}

} catch (error) {

reject(error)

}

},0)

})

return promise2

} else if (this.status===‘rejected’) {

let promise2=new Promise((resolve,reject)=>{

setTimeout(()=>{

try {

if (!this._isFunction(onRejected)) {

reject(this.reason)

} else {

this._resolvePromise(promise2,onRejected(this.reason))

}

} catch (error) {

reject(error)

}

},0)

})

return promise2

} else if (this.status===‘pending’)  {

let promise2=new Promise((resolve,reject)=>{

this.fulfilled_callbacks.push(()=>{

try {

if (!this._isFunction(onFulfilled)) {

resolve(this.value)

} else {

this._resolvePromise(promise2,onFulfilled(this.value))

}

} catch (error) {

reject(error)

}

})

this.rejected_callbacks.push(()=>{

try {

if (!this._isFunction(onRejected)) {

reject(this.reason)

} else {

this._resolvePromise(promise2,onRejected(this.reason))

}

} catch (error) {

reject(error)

}

})

})

return promise2

}

}

catch=onRejected=>this.then(null,onRejected)

finally=onFinished=>this.then(onFinished,onFinished)

static deferred(){

let deferred={}

deferred.promise=new Promise((resolve,reject)=>{

deferred.resolve=resolve

deferred.reject=reject

})

return deferred

}

static resolve(value) {

if (value instanceof Promise) return value

return new Promise(resolve=>resolve(value))

}

static reject=reason=>{return new Promise((resolve, reject)=>reject(reason))}

static all(promiseList) {

return new Promise((resolve,reject)=>{

if (promiseList.length===0) return resolve([])

let result=[],count=0

promiseList.forEach((promise,index)=>{

Promise.resolve(promise).then(value=>{

result[index]=value

if (++count===promiseList.length) resolve(result)

},reason=>reject(reason))

})

})

}

static race(promiseList) {

return new Promise((resolve,reject)=>{

if (promiseList.length===0) return resolve()

promiseList.forEach(promise=>{

Promise.resolve(promise)

.then(value=>resolve(value),reason=>reject(reason))

})

})

}

static allSettled(promiseList) {

return new Promise(resolve=>{

let result=[],count=0

if (len===0) return resolve(result)

promiseList.forEach((promise,i)=>{

Promise.resolve(promise).then(value=>{

result[i]={

status:‘fulfilled’,

value:value

}

if (++count===promiseList.length) resolve(result)

},reason=>{

result[i]={

status:‘rejected’,

reason:reason

}

if (++count===promiseList.length) resolve(result)

})

})

})

}

_resolve=value=>{

if (this.status!==‘pending’) return

setTimeout(()=>{

this.status =‘fulfilled’

this.value = value

this.fulfilled_callbacks.forEach(cb=>cb(this.value))

},0)

}

_reject=reason=>{

if (this.status!==‘pending’) return

setTimeout(()=>{

this.reason = reason

this.status =‘rejected’

this.rejected_callbacks.forEach(cb=>cb(this.reason))

},0)

}

_isFunction=f=>Object.prototype.toString.call(f).toLocaleLowerCase()===‘[object function]’

_isObject=o=>Object.prototype.toString.call(o).toLocaleLowerCase()===‘[object object]’

_resolvePromise(promise,x){

if (promise===x) {

promise._reject(new TypeError(‘cant be the same’))

return

}

if (x instanceof Promise) {

if (x.status===‘fulfilled’) {

promise._resolve(x.value)

} else if (x.status===‘rejected’) {

promise._reject(x.reason)

} else if (x.status===‘pending’) {

x.then(value=>{

this._resolvePromise(promise,value)

},reason=>{

promise._reject(reason)

})

}

return

}

if (this._isObject(x)||this._isFunction(x)) {

let then

try {

then=x.then

} catch (error) {

promise._reject(error)

return

}

if (this._isFunction(then)) {

let called=false

try {

then.call(x,value=>{

if (called) return

called=true

this._resolvePromise(promise,value)

},reason=>{

if (called) return

called=true

promise._reject(reason)

})

} catch (error) {

if (called) return

promise._reject(error)

}

} else {

promise._resolve(x)

}

} else {

promise._resolve(x)

}

}

}

module.exports = Promise`

HTTP请求


AJAX封装

``function ajax(method,url,params,callback) {

//对参数进行处理

method=method.toUpperCase()

let post_params=null

let get_params=‘’

if (method===‘GET’) {

if (typeof params===‘object’) {

let tempArr=[]

for (let key in params) {

tempArr.push(${key}=${params[key]})

}

params=tempArr.join(‘&’)

}

get_params=?${params}

} else {

post_params=params

}

//发请求

let xhr=new XMLHttpRequest()

xhr.onreadystatechange=function(){

if (xhr.readyState!==4) return

callback(xhr.responseText)

}

xhr.open(method,url+get_params,false)

if (method===‘POST’)

xhr.setRequestHeader(‘Content-Type’,‘application/x-www-form-urlencoded’)

xhr.send(post_params)

}

ajax(‘get’,‘https://www.baidu.com’,{id:15},data=>console.log(data))``

JSONP

``function jsonp(url, params_obj, callback) {

//创建一个供后端返回数据调用的函数名

let funcName = ‘jsonp_’ + Data.now() + Math.random().toString().substr(2, 5)

//将参数拼接成字符串

if (typeof params===‘object’) {

let temp=[]

for (let key in params) {

temp.push(${key}=${params[key]})

}

params=temp.join(‘&’)

}

//在html中插入

let script=document.createElement(‘script’)

script.src=${url}?${params}&callback=${funcName}

document.body.appendChild(script)

//在本地设置供后端返回数据时调用的函数

window[funcName]=data=>{

callback(data)

delete window[funcName]

document.body.removeChild(script)

}

}

//使用方法

jsonp(‘http://xxxxxxxx’,{id:123},data=>{

//获取数据后的操作

})`` 
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

最后

前端CSS面试题文档,JavaScript面试题文档,Vue面试题文档,大厂面试题文档,需要的读者可以戳这里免费领取!

data=>console.log(data))``

JSONP

``function jsonp(url, params_obj, callback) {

//创建一个供后端返回数据调用的函数名

let funcName = ‘jsonp_’ + Data.now() + Math.random().toString().substr(2, 5)

//将参数拼接成字符串

if (typeof params===‘object’) {

let temp=[]

for (let key in params) {

temp.push(${key}=${params[key]})

}

params=temp.join(‘&’)

}

//在html中插入

let script=document.createElement(‘script’)

script.src=${url}?${params}&callback=${funcName}

document.body.appendChild(script)

//在本地设置供后端返回数据时调用的函数

window[funcName]=data=>{

callback(data)

delete window[funcName]

document.body.removeChild(script)

}

}

//使用方法

jsonp(‘http://xxxxxxxx’,{id:123},data=>{

//获取数据后的操作

})`` 
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-ohHwkSvs-1713838226673)]

[外链图片转存中…(img-My1UvFwA-1713838226673)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

[外链图片转存中…(img-I0WsafJX-1713838226674)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

[外链图片转存中…(img-ZLwNES5q-1713838226674)]

最后

前端CSS面试题文档,JavaScript面试题文档,Vue面试题文档,大厂面试题文档,需要的读者可以戳这里免费领取!

[外链图片转存中…(img-ETqKyxbN-1713838226674)]

[外链图片转存中…(img-Z8hNXqr3-1713838226675)]

  • 30
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值