web前端JS高阶面试题,2024我的前端大厂面试之旅

简介: web前端JS高阶面试题,2024我的前端大厂面试之旅

正文

return cloneTarget
} else {
return target
}
}
#####自定义instanceof工具函数
/*
自定义instanceof工具函数:
语法: myInstanceOf(obj, Type)
功能: 判断obj是否是Type类型的实例
实现: Type的原型对象是否是obj的原型链上的某个对象, 如果是返回true, 否则返回false
*/
export function myInstanceOf(obj, Type) {
// 得到原型对象
let protoObj = obj.proto
// 只要原型对象存在
while(protoObj) {
// 如果原型对象是Type的原型对象, 返回true
if (protoObj === Type.prototype) {
return true
}
// 指定原型对象的原型对象
protoObj = protoObj.proto
}
return false
}
#####自定义new工具函数
/*
自定义new工具函数
语法: newInstance(Fn, …args)
功能: 创建Fn构造函数的实例对象
实现: 创建空对象obj, 调用Fn指定this为obj, 返回obj
*/
export function newInstance(Fn, …args) {
// 创建一个新的对象
const obj = {}
// 执行构造函数
const result = Fn.apply(obj, args) // 相当于: obj.Fn()
// 如果构造函数执行的结果是对象, 返回这个对象
if (result instanceof Object) {
return result
}
// 如果不是, 返回新创建的对象
obj.proto.constructor = Fn // 让原型对象的构造器属性指向Fn
return obj
}
#####手写axios函数
/*
1. 函数的返回值为promise, 成功的结果为response, 失败的结果为error
2. 能处理多种类型的请求: GET/POST/PUT/DELETE
3. 函数的参数为一个配置对象
{
url: ‘’, // 请求地址
method: ‘’, // 请求方式GET/POST/PUT/DELETE
params: {}, // GET/DELETE请求的query参数
data: {}, // POST或DELETE请求的请求体参数
}
4. 响应json数据自动解析为js的对象/数组
/
/ 发送任意类型请求的函数 /
function axios({
url,
method=‘GET’,
params={},
data={}
}) {
// 返回一个promise对象
return new Promise((resolve, reject) => {
// 处理method(转大写)
method = method.toUpperCase()
// 处理query参数(拼接到url上) id=1&xxx=abc
/
{
id: 1,
xxx: ‘abc’
}
/
let queryString = ‘’
Object.keys(params).forEach(key => {
queryString += ${key}=${params[key]}&
})
if (queryString) { // id=1&xxx=abc&
// 去除最后的&
queryString = queryString.substring(0, queryString.length-1)
// 接到url
url += ‘?’ + queryString
}
// 1. 执行异步ajax请求
// 创建xhr对象
const request = new XMLHttpRequest()
// 打开连接(初始化请求, 没有请求)
request.open(method, url, true)
// 发送请求
if (method===‘GET’) {
request.send()
} else if (method===‘POST’ || method===‘PUT’ || method===‘DELETE’){
request.setRequestHeader(‘Content-Type’, ‘application/json;charset=utf-8’) // 告诉服务器请求体的格式是json
request.send(JSON.stringify(data)) // 发送json格式请求体参数
}
// 绑定状态改变的监听
request.onreadystatechange = function () {
// 如果请求没有完成, 直接结束
if (request.readyState!==4) {
return
}
// 如果响应状态码在[200, 300)之间代表成功, 否则失败
const {status, statusText} = request
// 2.1. 如果请求成功了, 调用resolve()
if (status>=200 && status<=299) {
// 准备结果数据对象response
const response = {
data: JSON.parse(request.response),
status,
statusText
}
resolve(response)
} else { // 2.2. 如果请求失败了, 调用reject()
reject(new Error('request error status is ’ + status))
}
}
})
}
/ 发送特定请求的静态方法 */
axios.get = function (url, options) {
return axios(Object.assign(options, {url, method: ‘GET’}))
}
axios.delete = function (url, options) {
return axios(Object.assign(options, {url, method: ‘DELETE’}))
}
axios.post = function (url, data, options) {
return axios(Object.assign(options, {url, data, method: ‘POST’}))
}
axios.put = function (url, data, options) {
return axios(Object.assign(options, {url, data, method: ‘PUT’}))
}
export default axios
#####自定义事件总线
/*
• 自定义事件总线
/
const eventBus = {}
/
{
add: [callback1, callback2]
delete: [callback3]
}
/
let callbacksObj = {}
/
绑定事件监听
/
eventBus.on = function (eventName, callback) {
const callbacks = callbacksObj[eventName]
if (callbacks) {
callbacks.push(callback)
} else {
callbacksObj[eventName] = [callback]
}
}
/
分发事件
/
eventBus.emit = function (eventName, data) {
const callbacks = callbacksObj[eventName]
if (callbacks && callbacks.length > 0) {
callbacks.forEach(callback => {
callback(data)
})
}
}
/
移除事件监听
*/
eventBus.off = function (eventName) {
if (eventName) {
delete callbacksObj[eventName]
} else {
callbacksObj = {}
}
}
export default eventBus
#####自定义消息订阅与发布
/*
自定义消息订阅与发布
/
const PubSub = {}
/
{
add: {
token1: callback1,
token2: callback2
},
update: {
token3: callback3
}
}
/
let callbacksObj = {} // 保存所有回调的容器
let id = 0 // 用于生成token的标记
// 1. 订阅消息
PubSub.subscribe = function (msgName, callback) {
// 确定token
const token = ‘token_’ + ++id
// 取出当前消息对应的callbacks
const callbacks = callbacksObj[msgName]
if (!callbacks) {
callbacksObj[msgName] = {
[token]: callback
}
} else {
callbacks[token] = callback
}
// 返回token
return token
}
// 2. 发布异步的消息
PubSub.publish = function (msgName, data) {
// 取出当前消息对应的callbacks
let callbacks = callbacksObj[msgName]
// 如果有值
if (callbacks) {
// callbacks = Object.assign({}, callbacks)
// 启动定时器, 异步执行所有的回调函数
setTimeout(() => {
Object.values(callbacks).forEach(callback => {
callback(data)
})
}, 0)
}
}
// 3. 发布同步的消息
PubSub.publishSync = function (msgName, data) {
// 取出当前消息对应的callbacks
const callbacks = callbacksObj[msgName]
// 如果有值
if (callbacks) {
// 立即同步执行所有的回调函数
Object.values(callbacks).forEach(callback => {
callback(data)
})
}
}
/
4. 取消消息订阅
1). 没有传值, flag为undefined
2). 传入token字符串
3). msgName字符串
*/
PubSub.unsubscribe = function (flag) {
// 如果flag没有指定或者为null, 取消所有
if (flag === undefined) {
callbacksObj = {}
} else if (typeof flag === ‘string’) {
if (flag.indexOf(‘token_’) === 0) { // flag是token
// 找到flag对应的callbacks
const callbacks = Object.values(callbacksObj).find(callbacks => callbacks.hasOwnProperty(flag))
// 如果存在, 删除对应的属性
if (callbacks) {
delete callbacks[flag]
}
} else { // flag是msgName
delete callbacksObj[flag]
}
} else {
throw new Error(‘如果传入参数, 必须是字符串类型’)
}
}
export default PubSub
#####自定义数组声明式系列方法
/*
实现数组声明式处理系列工具函数
/
/
实现map()
/
export function map (array, callback) {
const arr = []
for (let index = 0; index < array.length; index++) {
arr.push(callback(array[index], index))
}
return arr
}
/
实现reduce()
/
export function reduce (array, callback, initValue) {
let result = initValue
for (let index = 0; index < array.length; index++) {
// 调用回调函数将返回的结果赋值给result
result = callback(result, array[index], index)
}
return result
}
/
实现filter()
/
export function filter(array, callback) {
const arr = []
for (let index = 0; index < array.length; index++) {
if (callback(array[index], index)) {
arr.push(array[index])
}
}
return arr
}
/
实现find()
/
export function find (array, callback) {
for (let index = 0; index < array.length; index++) {
if (callback(array[index], index)) {
return array[index]
}
}
return undefined
}
/
实现findIndex()
/
export function findIndex (array, callback) {
for (let index = 0; index < array.length; index++) {
if (callback(array[index], index)) {
return index
}
}
return -1
}
/
实现every()
/
export function every (array, callback) {
for (let index = 0; index < array.length; index++) {
if (!callback(array[index], index)) { // 只有一个结果为false, 直接返回false
return false
}
}
return true
}
/
实现some()
*/
export function some (array, callback) {
for (let index = 0; index < array.length; index++) {
if (callback(array[index], index)) { // 只有一个结果为true, 直接返回true
return true
}
}
return false
}
export function test() {
console.log(‘test()222’)
}
#####手写Promise
const PENDING = ‘pending’ // 初始未确定的状态
const RESOLVED = ‘resolved’ // 成功的状态
const REJECTED = ‘rejected’ // 失败的状态
/*
Promise构造函数
/
function Promise(excutor) {
const self = this // Promise的实例对象
self.status = PENDING // 状态属性, 初始值为pending, 代表初始未确定的状态
self.data = undefined // 用来存储结果数据的属性, 初始值为undefined
self.callbacks = [] // {onResolved(){}, onRejected(){}}
/
将promise的状态改为成功, 指定成功的value
/
function resolve(value) {
// 如果当前不是pending, 直接结束
if (self.status !== PENDING) return
self.status = RESOLVED // 将状态改为成功
self.data = value // 保存成功的value
// 异步调用所有缓存的待执行成功的回调函数
if (self.callbacks.length > 0) {
// 启动一个延迟时间为0的定时器, 在定时器的回调中执行所有成功的回调
setTimeout(() => {
self.callbacks.forEach(cbsObj => {
cbsObj.onResolved(value)
})
})
}
}
/
将promise的状态改为失败, 指定失败的reason
/
function reject(reason) {
// 如果当前不是pending, 直接结束
if (self.status !== PENDING) return
self.status = REJECTED // 将状态改为失败
self.data = reason // 保存reason数据
// 异步调用所有缓存的待执行失败的回调函数
if (self.callbacks.length > 0) {
// 启动一个延迟时间为0的定时器, 在定时器的回调中执行所有失败的回调
setTimeout(() => {
self.callbacks.forEach(cbsObj => {
cbsObj.onRejected(reason)
})
})
}
}
// 调用excutor来启动异步任务
try {
excutor(resolve, reject)
} catch (error) { // 执行器执行出错, 当前promise变为失败
console.log(‘-----’)
reject(error)
}
}
/
用来指定成功/失败回调函数的方法
1). 如果当前promise是resolved, 异步执行成功的回调函数onResolved
2). 如果当前promise是rejected, 异步执行成功的回调函数onRejected
3). 如果当前promise是pending, 保存回调函数
返回一个新的promise对象
它的结果状态由onResolved或者onRejected执行的结果决定
2.1). 抛出error ==> 变为rejected, 结果值为error
2.2). 返回值不是promise ==> 变为resolved, 结果值为返回值
2.3). 返回值是promise ===> 由这个promise的决定新的promise的结果(成功/失败)
/
Promise.prototype.then = function (onResolved, onRejected) {
const self = this
onResolved = typeof onResolved === ‘function’ ? onResolved : value => value // 将value向下传递
onRejected = typeof onRejected === ‘function’ ? onRejected : reason => {
throw reason
} // 将reason向下传递
return new Promise((resolve, reject) => { // 什么时候改变它的状态
/
1. 调用指定的回调函数
2. 根据回调执行结果来更新返回promise的状态
/
function handle(callback) {
try {
const result = callback(self.data)
if (!(result instanceof Promise)) { // 2.2). 返回值不是promise ==> 变为resolved, 结果值为返回值
resolve(result)
} else { // 2.3). 返回值是promise ===> 由这个promise的决定新的promise的结果(成功/失败)
result.then(
value => resolve(value),
reason => reject(reason)
)
// result.then(resolve, reject)
}
} catch (error) { // 2.1). 抛出error ==> 变为rejected, 结果值为error
reject(error)
}
}
if (self.status === RESOLVED) {
setTimeout(() => {
handle(onResolved)
})
} else if (self.status === REJECTED) {
setTimeout(() => {
handle(onRejected)
})
} else { // PENDING
self.callbacks.push({
onResolved(value) {
handle(onResolved)
},
onRejected(reason) {
handle(onRejected)
}
})
}
})
}
/
用来指定失败回调函数的方法
catch是then的语法糖
/
Promise.prototype.catch = function (onRejected) {
return this.then(undefined, onRejected)
}
/
用来返回一个指定vlaue的成功的promise
value可能是一个一般的值, 也可能是promise对象
*/
Promise.resolve = function (value) {
return new Promise((resolve, reject) => {

最后

javascript是前端必要掌握的真正算得上是编程语言的语言,学会灵活运用javascript,将对以后学习工作有非常大的帮助。掌握它最重要的首先是学习好基础知识,而后通过不断的实战来提升我们的编程技巧和逻辑思维。这一块学习是持续的,直到我们真正掌握它并且能够灵活运用它。如果最开始学习一两遍之后,发现暂时没有提升的空间,我们可以暂时放一放。继续下面的学习,javascript贯穿我们前端工作中,在之后的学习实现里也会遇到和锻炼到。真正学习起来并不难理解,关键是灵活运用。


相关文章
|
2月前
|
前端开发 JavaScript 开发者
JavaScript:无处不在的Web语言
JavaScript:无处不在的Web语言
|
2月前
|
前端开发 JavaScript 开发者
JavaScript:构建动态Web的核心力量
JavaScript:构建动态Web的核心力量
|
2月前
|
JavaScript 前端开发 开发者
JavaScript:驱动现代Web的核心引擎
JavaScript:驱动现代Web的核心引擎
|
6月前
|
前端开发 算法 API
构建高性能图像处理Web应用:Next.js与TailwindCSS实践
本文分享了构建在线图像黑白转换工具的技术实践,涵盖技术栈选择、架构设计与性能优化。项目采用Next.js提供优秀的SSR性能和SEO支持,TailwindCSS加速UI开发,WebAssembly实现高性能图像处理算法。通过渐进式处理、WebWorker隔离及内存管理等策略,解决大图像处理性能瓶颈,并确保跨浏览器兼容性和移动设备优化。实际应用案例展示了其即时处理、高质量输出和客户端隐私保护等特点。未来计划引入WebGPU加速、AI增强等功能,进一步提升用户体验。此技术栈为Web图像处理应用提供了高效可行的解决方案。
|
2月前
|
JavaScript 前端开发 物联网
JavaScript:驱动现代Web的核心引擎
JavaScript:驱动现代Web的核心引擎
|
7月前
|
JavaScript 前端开发 API
|
8月前
|
JSON 自然语言处理 前端开发
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
460 72
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
|
5月前
|
JSON JavaScript 前端开发
JavaScript入门干货:蓝桥杯Web组分章学习笔记(基于蓝桥云课《JavaScript基础入门》)
这是一份详尽的JavaScript学习笔记,涵盖基础到进阶内容。包括变量、运算符、数组、字符串操作,DOM/BOM事件处理,内置对象(如Array、Date、Math)用法,JSON格式解析,以及函数作用域与闭包等核心概念。同时深入探讨值类型和引用类型的差异、异常处理机制,并介绍函数高级特性如call/apply/bind方法、递归及arguments对象。代码按章节分点整理,注释细致,适合初学者系统掌握JavaScript编程知识。
113 2
|
7月前
|
前端开发 JavaScript 数据可视化
58K star!这个让网页动起来的JS库,前端工程师直呼真香!
Anime.js 是一款轻量级但功能强大的JavaScript动画引擎,它能够以最简单的方式为网页元素添加令人惊艳的动效。这个项目在GitHub上已经获得58,000+星标,被广泛应用于电商页面、数据可视化、游戏开发等场景。
286 8
|
8月前
|
资源调度 JavaScript 前端开发
前端开发必备!Node.js 18.x LTS保姆级安装教程(附国内镜像源配置)
本文详细介绍了Node.js的安装与配置流程,涵盖环境准备、版本选择(推荐LTS版v18.x)、安装步骤(路径设置、组件选择)、环境验证(命令测试、镜像加速)及常见问题解决方法。同时推荐开发工具链,如VS Code、Yarn等,并提供常用全局包安装指南,帮助开发者快速搭建高效稳定的JavaScript开发环境。内容基于官方正版软件,确保合规性与安全性。
7410 23
下一篇
oss云网关配置