深度优先实现
`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前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合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)]