面试其实也是工作经验的总结,在工作之余,将工作中的问题记录总结,也是为下一份工作面试打好基础。
跨域是一个比较大的话题,问题本身在开发过程中比较常见的问题,
对跨域的理解和解决方法可以点击这里
防抖:防止抖动、阻止用户行为多次触发请求。即是高频触发的事件,一定时间内、只有最后一次被触发生效。
使用场景:
代码实现封装防抖:
function dobunce (fn, waitTime){
let timer = null;
return (...arg) => {
if(timer) clearTimeout(timer)
timer = setTimerout(()=>{
fn(...arg)
},waitTime)
}
}
节流:节约流量、控制事件的发生频率,即是高频触发的事件、一定时间内只触发一次。
使用场景:
代码实现:
function throttle(fn,waitTime){
let timer = null;
return (...args)=>{
if(timer) return
timer = setTimeout(()=>{
fn(...args)
timer=null
}, waitTime)
}
}
判断元素是否在视口内:需要了解浏览器判断一个元素位置的方法。首先我们需要了解怎么判断浏览器的宽、高。
//兼容所有浏览,获取浏览器的宽高的方法;
const w=window.innerWidth
|| document.documentElement.clientWidth
|| document.body.clientWidth;
const h=window.innerHeight
|| document.documentElement.clientHeight
|| document.body.clientHeight;
//window 常用的方法
window.close() //关闭浏览器窗口
window.open() // 开启浏览器窗口
window.resizeTo() // 调整浏览器窗口
window.moveTo() //移动浏览器
同时我们还需要了解元素属性;
getBoundingClientRect();
Element.getBoundingClientRect() 方法返回一个 DOMRect 对象,其提供了元素的大小及其相对于视口的位置。拥有left, top, right, bottom, x, y, width, height属性。
使用 getBoundingClientRect 方法 判断元素是否在视口内部、公式为:
el.getBoundingClientRect().top < viewHight(视口高度)
代码实现:
const elIsInViewPort = (el) => {
const viewHight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
const elToViewHeight = el.getBoundingClientRect()?.top;
return elToViewHeight <= viewHight + 100 //+100 目的是为了提前加载数据
}
IntersectionObserver 接口;
IntersectionObserver 接口(从属于 Intersection Observer API)提供了一种异步观察目标元素与其祖先元素
顶级文档视口(viewport)交叉状态的方法。其祖先元素或视口被称为根(root)
了解更多 IntersectionObserver API 移步到这里
使用 IntersectionObserver 判断元素是否在视口内 代码实现方法
//
const intersectionObserver = new IntersectionObserver((entries)=>{
// 如果 intersectionRatio 为 0,则目标在视野外,
if(entries.length < 1) return
entries.forEatch((target)=>{
if(target.isIntersecting){
//停止对元素的观察
intersectionObserver.unobserve(target)
}
})
})
const elArr = [...document.querySelectorArr('.selectEle')]
elArr.forEatch((item)=>{
intersectionObserver.observe(item) //对元素进行监听;
})
let ,const, var 都是js 中使用来申明变量的方法。
var 声明的变量 为全局变量,及是 window 下的变量,存在变量提升问题。
let、 const 为es6 新提出的申明变量的方法,申明的变量为块级作用域、
const 声明 的变量为常量、必须初始化值、不能修改变量值、否则会报错。
let 申明的块级作用域变量,可以修改变量值。
let const 声明的变量都不能重复声明,重复声明会报错。var 声明重复变量不报错会覆盖前面变量的值。
promise js 使用来异步执行代码的方法,由于js 执行代码为同步的,一次只执行一次任务,阻塞其他任务。
js中数据类型:
类型 | typeOf 返回值 |
---|---|
Null | “Object” |
Undefined | “Object” |
Boolean | “boolean” |
Number | “number” |
BigInt | “bigint” |
String | “string” |
Symbol | “symbol” |
判断数据类型方法
方法一:typeOf
能够精确的返回数据的基本数据类型,但是不能明确判断出, Null、 Underfined 对象值,
方法二: instanceOf
可以拿根据 instanceOf 判断对象是继承哪一个原始类型,判断方法为根据js原型链特性,逐级向上找到根节点
代码实现instanceOf
const myInstanceOf = (obj,type) =>{
if(typeOf obj !== 'object' || obj == null) return false
let proto = Object.getProtoTypeOf(obj)
while(true){
if(proto === null) return false
else if(proto === type.protoType){
return true
}else {
proto = Object.getProtoTypeOf(proto)
}
}
}
//使用方法
const s = 'abc'
myInstanceOf(s, 'string') // true
方法三: Object.protoType.toString.call(obj)
toString 方法为对象原型上的方法,直接调用toString 方法 返回 “[object: ‘Xxxxx’]” , ‘Xxxxx’ 就为对象的类型,object 调用toString 方法 直接返回 “[object: ‘object’]” 字符串, 其他类型的值调用需要使用call() 调用才能返回正确的值。
Object.protoType.toString({
}) // "[object Object]"
Object.protoType.toString.call('str') //"[object String]"
Object.protoType.toString.call(124) // "[object Number]"
其他也可以使用 数据类型的转换
如: Boolean() 类型转换 Number() 类型转换
Axios和Ajax是两种不同的技术,用于实现前后端数据交互。
Axios是一个基于Promise的HTTP客户端,可以用于浏览器和Node.js环境。它支持跨域请求、拦截请求和响应、取消请求等功能。Axios可以通过简单的API发送HTTP请求,并且可以处理响应结果。它是一个相对较新的技术,逐渐取代了旧的Ajax技术。
Ajax(Asynchronous JavaScript and XML)是一种用于创建异步请求的技术。它可以使网页在不重新加载的情况下更新部分内容,提升用户体验。Ajax可以使用XMLHttpRequest对象来发送HTTP请求,并通过回调函数处理响应结果。
所以,主要区别如下:
通过DOM操作,可以实现以下功能:
获取元素:使用document对象的方法,如getElementById、getElementsByTagName、getElementsByClassName等来获取HTML文档中的元素。
修改元素的内容:使用innerHTML属性来修改元素的内容,或使用textContent属性来修改文本内容。
修改元素的样式:使用style属性来修改元素的样式,如颜色、背景、字体等。
修改元素的属性:使用setAttribute方法来修改元素的属性,如class、id、src等。
创建和删除元素:使用createElement方法创建新的元素,并使用appendChild或insertBefore方法将其插入到指定位置,使用removeChild方法将元素从文档中删除。
监听事件:使用addEventListener方法来监听元素上的事件,如点击、鼠标移动等。
修改表单数据:可以使用JavaScript来获取和修改表单元素的值,如input、select、textarea等。
通过以上DOM操作,可以实现动态地更新HTML文档的内容、样式和行为,使网页具有更好的交互性和用户体验。HTML中的DOM操作。
使用方式:
设计思路:
命名规范:
总结起来,普通函数主要用于解决具体问题,而自定义hook主要用于复用和共享逻辑。自定义hook的设计目标是将组件之间的逻辑提取出来,使得逻辑更加清晰、可重用,并且符合React的设计理念。普通函数与自定义hook的区别。
SSR(Server-Side Rendering)是一种Web开发技术,它在服务器端生成完整的HTML内容,然后将其发送到客户端浏览器进行展示。与传统的客户端渲染(CSR)不同,客户端渲染是指在浏览器中使用JavaScript来动态生成HTML内容。
SSR的主要优势是改善了网页的加载性能和搜索引擎优化(SEO)。由于页面在服务器端生成,用户在请求页面时会直接获得完整的HTML内容,因此首次加载速度比CSR更快,且可以提供更好的搜索引擎抓取和索引。
SSR的实现需要使用一些特定的框架或库,如React的Next.js、Vue的Nuxt.js等。这些工具提供了服务端渲染的功能,可以将组件在服务器端渲染为HTML,并将其与浏览器端的JavaScript进行关联,以实现客户端的交互功能。
SSR的基本流程包括以下几个步骤:
需要注意的是,由于SSR需要在服务器端进行组件渲染,因此对服务器的负载有一定的影响。此外,SSR也增加了开发的复杂性,因为需要同时处理服务器端和客户端的渲染逻辑。
浏览器可以通过以下几种方式进行静态资源缓存:
设置HTTP缓存头:浏览器通过设置响应头中的缓存相关字段,指示浏览器对静态资源进行缓存。常用的响应头字段有:
max-age=3600
表示资源在一个小时内有效。If-Modified-Since
字段将上次的最后修改时间发送给服务器,如果资源在服务器上的最后修改时间仍然一致,服务器会返回一个304 Not Modified
的响应,表示资源未变化,浏览器可以使用缓存的版本。ETag/If-None-Match: 服务器对于每个资源生成一个唯一的标识符,称为ETag,浏览器在下一次请求时通过If-None-Match
字段将上次请求中服务器返回的ETag发送给服务器,如果这个资源的ETag仍然一致,服务器会返回一个304 Not Modified
的响应。
Service Worker缓存:通过Service Worker技术,浏览器可以在离线状态或网络不稳定的情况下,拦截对静态资源的请求并返回缓存的版本。
localStorage/IndexedDB: 将静态资源缓存到本地存储(localStorage或IndexedDB)中,下次使用时直接从本地读取。
需要注意的是,浏览器缓存是由浏览器自行处理的,开发人员只需在服务器端设置合适的响应头字段和缓存策略即可。另外,浏览器缓存只适用于静态资源,动态资源每次访问都会向服务器发起请求。
在前端开发中,样式覆盖是处理样式冲突的重要问题。以下是一些常见的处理样式覆盖的方法:
使用更具体的选择器:如果多个样式规则应用于同一个元素,可以使用更具体的选择器来指定优先级。例如,使用id选择器比class选择器具有更高的优先级。
使用!important:使用!important声明可以将样式规则的优先级提升到最高级别,但应谨慎使用此方法,因为它可能会导致样式无法继承和覆盖。