面试速通
最后更新时间:
面试问题集合 https://fe-interview.pangcy.cn/docs/engineering/vite/vite-06/ ## Todo - 函数装饰器 ## function和箭头函数区别 箭头函数定义时根据上下文确定this,适用于回调函数 function适用于对象的方法
防抖节流
防抖在连续的事件,只需触发一次回调的场景有:搜索框搜索输入。只需用户最后一次输入完,再发送请求,事件之后延迟n ms,看看还有没有事件 节流:在间隔一段时间执行一次回调的场景
函数压缩
问题: 为什么compose2不行 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51let compose = (...fns) => {
let res = (...args) => args;
for (let fn of fns) {
res = (function(fn, res) {
return (...args) => {
return fn(res(...args));
};
})(fn, res);
}
return res;
}
let compose2 = (...fns) => {
let res = (...args) => args;
for (let fn of fns) {
res = (...args) => {
return fn(res(...args));
};
}
return res;
}
/*
let compose2 = (...fns) => {
let res = (...args) => args;
for (let fn of fns) {
let fnn = fn, ress = res;
res = (...args) => {
return fnn(ress(...args));
};
}
return res;
}
*/
let a = (str) => str + 'a';
let b = (str) => str + 'b';
let c = (str) => str + 'c';
let d = (str) => str + 'd';
let e = compose2(a, b, c, d);
console.log(e);
console.log(e("begin"));
js number范围
在 JavaScript 中,数字(Number)类型是基于 IEEE 754
标准的双精度 64 位浮点数。这意味着 JavaScript
中的数字可以表示非常大的范围,但有一个最大安全整数值。
跨域解决办法
CORS
浏览器会阻止这种请求, 当浏览器检测到跨域请求时,会先发送一个
OPTIONS 请求(预检请求)到目标服务器,
服务器需要在响应头中返回 Access-Control-Allow-Origin 等
CORS 相关头信息,以告知浏览器是否允许该请求。 ### jsonp
jsonp的原理就是通过<script>
标签绕过浏览器的同源策略。服务器返回的数据被包装在一个回调函数中(例如
callback({"data": "value"})),客户端通过定义好的回调函数处理数据。
容易受到 XSS(跨站脚本攻击)
nginx
- 增加cors相关
- 进行反向代理(把 http://front_server/api 转到
http://backend_server)
- 正向代理:代理客户端,向服务器发送请求,隐藏客户端身份(如 VPN)。
- 反向代理:代理后端服务器,接收客户端请求并转发,隐藏后端服务器。
部署
先来说下前端项目的部署,一般来说有以下几个步骤:项目打包,上传到服务器,域名解析,SSL 证书,申请Nginx ,配置CDN 加速。 vercel自动化部署:如果是自己做一些小项目,再也不用每次修改代码之后还要打包上传到服务器了,只需要把代码提交到仓库,Vercel 会自动触发部署,部署完成之后再通知你,这体验真的是无比丝滑。
http缓存
在 HTTP Caching 标准中,有两种不同类型的缓存:私有缓存(存在客户端)和共享缓存(共享缓存位于客户端和服务器之间)。

响应age 1
Cache-Control: max-age=604800
过时的缓存不会立即被丢弃。HTTP 有一种机制,可以通过询问源服务器这个缓存是否真的过期。这称为验证,有时也称为重新验证。
1 | |
文档没被修改过,条件就为假,服务端会返回一个 304 NotModified 响应报文
1 | |
重写,修改不重要,or 在毫秒级间隙发生变化(if modified since不够用)
网络攻击 XSS and CSRF
XSS: 注入脚本,让受害者浏览器执行,来窃取cookie - 非持久型 XSS(反射型 XSS)诱骗点击url - 持久型 XSS 漏洞,一般存在于 Form 表单提交等交互功能,如文章留言,提交文本信息等,黑客利用的 XSS 漏洞,将内容经正常功能提交进入数据库持久保存
CSRF:诱导受害者发送伪造的请求到目标网站,利用受害者的身份(cookie)执行未经授权的操作。(目标网站的服务器也被篡改)
解决办法: - xxs 可以设置csp,让代码不能执行 - xxs 可以转义字符 -
CSRF 攻击依赖于伪造用户身份发送请求,但攻击者无法获取受害者的 CSRF
Token(因为它存储在会话中或受同源策略保护)。 -
cookie标记samesite,跨域请求不发送cookie - 敏感信息使用 httponly cookie
(xss) - Cookie
是存储在用户浏览器端的小段数据,用于跟踪用户会话等信息。而 HttpOnly 是
Cookie 的一个属性。 - 当设置为 HttpOnly 时,该 Cookie 只能通过 HTTP 或
HTTPS 协议进行访问,不能被客户端脚本(如
JavaScript)访问。这有助于防止一些跨站脚本攻击(XSS)。因为如果 Cookie
被恶意脚本访问到,攻击者可能会窃取用户的会话信息等敏感数据。 -
不要设置Access-Control-Allow-Origin=*
事件委托
dom元素的事件自动冒泡 动态生成的元素(如列表);减少内存占用和提高性能;统一处理相似元素的事件
浅拷贝深拷贝分别怎么实现
浅拷贝用展开运算符(...) 深拷贝用structuredClone()
JSON.stringify实现深拷贝有什么问题:会忽略函数,date,error等对象会变成字符串,对象无法循环引用
CommonJS 和 ES6 模块系统区别
es6 异步加载,静态分析,也支持动态导入,导出值实时绑定(响应式)
ts class写法
class Person { name: string; age: number;
constructor(name: string, age: number) { this.name = name; this.age = age; }
sayHello(): void {
console.log(Hello, my name is ${this.name} and I am ${this.age} years old.);
} }
// 创建实例 const person = new Person('Alice', 25); person.sayHello(); // 输出: Hello, my name is Alice and I am 25 years old.
worker
new Worker('worker.js') 主程序/worker worker/self.postmessage worker/self.onmessage/onerror AddEventListener 和promise一起 ommessage->resolve onerror->reject
前面说过,主线程与 Worker 之间的通信内容,可以是文本,也可以是对象。需要注意的是,这种通信是拷贝关系,即是传值而不是传址,Worker 对通信内容的修改,不会影响到主线程。事实上,浏览器内部的运行机制是,先将通信内容串行化,然后把串行化后的字符串发给 Worker,后者再将它还原。“串行化”是指把一个对象或者数据结构转换成一个字节序列的过程,这样做的目的是为了方便存储或者传输。
slice
python [a:b] = js .slice(a, b)
内存泄漏
https://elvinn.wiki/nodejs/memory.html 1. 全局变量 2. 闭包引用 3. 事件绑定(dom移除时没有移除eventlistener,这是node?? 4. 缓存爆炸 heapdump
| 特性 | computed |
watch |
|---|---|---|
| 缓存机制 | 有缓存,只有依赖项变化时才会重新计算 | 无缓存,每次依赖项变化都会执行回调 |
| 更新机制 | 同步更新 | 异步更新 |
| 用途 | 用于基于现有数据派生新数据 | 用于监听数据变化并执行复杂逻辑 |
| 依赖响应式 | 自动追踪依赖项 | 需要手动指定依赖项 |
var 声明提前
这里声明了变量,js解释器“前瞻性”查找所有变量定义,把它们“提升”到函数顶部
首屏优化
懒加载
有时候我们想把某个路由下的所有组件都打包在同个异步块 (chunk)
中。在Vite中,你可以在rollupOptions下定义分块:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20// 将 import UserDetails from './views/UserDetails.vue'
// 替换成 const UserDetails = () => import('./views/UserDetails.vue')
// vite.config.js
export default defineConfig({
build: {
rollupOptions: {
// https://rollupjs.org/guide/en/#outputmanualchunks
output: {
manualChunks: {
'group-user': [
'./src/UserDetails',
'./src/UserDashboard',
'./src/UserProfileEdit',
],
},
},
},
},
})
css和js阻塞渲染的问题
https://blog.csdn.net/qq_44318215/article/details/125392575