继承方式
一、原型链的继承
优点:父类方法可以复用
缺点:父类所有的引用类型的会被共享
SubType.prototype SubType.prototype = new SuperType();
二、构造函数继承,无法使用父类的 prototype
优点:
缺点;
- 只能继承父类的实例属性和方法,不能继承原型属性/方法
- 无法实现复用,每个子类都有父类实例函数的副本,影响性能
function SubType(){ //继承自 SuperType SuperType.call(this); }
三、组合式继承
将原型链继承和构造函数继承结合
会使得实例对象时,原型中会存在两份相同的属性/方法,每个实例一份,原型上也有一份
js
function SubType(name, age) {
// 继承属性
// 第二次调用SuperType()
SuperType.call(this, name);
this.age = age;
}
// 继承方法
// 构建原型链
// 第一次调用SuperType()
SubType.prototype = new SuperType();
// 重写SubType.prototype的constructor属性,指向自己的构造函数SubType
SubType.prototype.constructor = SubType;
四、寄生组合式继承
结合借用构造函数传递参数和寄生模式实现继承
js
function inheritPrototype(subType, superType) {
var prototype = Object.create(superType.prototype); // 创建对象,创建父类原型的一个副本
prototype.constructor = subType; // 增强对象,弥补因重写原型而失去的默认的constructor 属性
subType.prototype = prototype; // 指定对象,将新创建的对象赋值给子类的原型
}
// 借用构造函数传递增强子类实例属性(支持传参和避免篡改)
function SubType(name, age) {
SuperType.call(this, name);
this.age = age;
}
响应式原理
1.被监控的函数
render
computed
watchEffect
watch
- 依赖收集(Dep)
- 数据劫持(Observer)
- 观察者(Watcher)
- 视图更新(Compile)
observe
劫持数据 →Dep
收集Watcher
→ 数据变化dep.notify()
→Watcher.update()
驱动视图更新
Observer 负责将数据转换成 getter/setter 形式;
Dep 负责管理数据的依赖列表;是一个发布订阅模式,上游对接 Observer,下游对接 Watcher
Watcher 是实际上的数据依赖,负责将数据的变化转发到外界(渲染、回调);
首先将 data 传入 Observer 转成 getter/setter 形式;当 Watcher 实例读取数据时,会触发 getter,被收集到 Dep 仓库中;当数据更新时,触发 setter,通知 Dep 仓库中的所有 Watcher 实例更新,Watcher 实例负责通知外界
组合式与选项式的区别
路由模式
for 与 forEach 哪个更快
分情况
量级小没区别
forEach 需要执行回调函数
对于回调函数复杂的情况,for 更快
对于稀疏数组[1,6]+简单累加 时 JIT 优化,forEach 更快
BFC
BFC 是块级格式上下文 ,BFC 是一个独立的布局环境 ,它的元素布局不会受外部影响。
创建 BFC 的条件:
- 根元素:body;
- 元素设置浮动:float 除 none 以外的值;
- 元素设置绝对定位,固定定位:position (absolute、fixed);
- display 值为:inline-block、table-cell 、table-caption、flex等;
- overflow 值为:hidden、auto、scroll;
BFC 的作用:
- 解决 margin 的重叠问题:由于 BFC 是一个独立的区域,内部的元素和外部的元素互不影响,将两个元素变为两个 BFC,就解决了 margin 重叠的问题。
- 解决高度塌陷的问题 :在对子元素设置浮动后,父元素会发生高度塌陷,也就是父元素的高度变为 0。解决这个问题,只需要把父元素变成一个 BFC。常用的办法是给父元素设置
overflow:hidden
。 - 创建自适应两栏布局:可以用来创建自适应两栏布局:左边的宽度固定,右边的宽度自适应。
闭包
闭包是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,创建的函数可以访问到当前函数的局部变量。
闭包有两个常用的用途;
- 闭包的第一个用途是使我们在函数外部能够访问到函数内部的变量。通过使用闭包,可以通过在外部调用闭包函数,从而在外部访问到函数内部的变量,可以使用这种方法来创建私有变量。
- 闭包的另一个用途是使已经运行结束的函数上下文中的变量对象继续留在内存中,因为闭包函数保留了这个变量对象的引用,所以这个变量对象不会被回收。
原型和原型链
TS
interface 与 type
![[af9d345b26ad064f843b829c042a095b.png]]
泛型
设计模式
单例模式,多例模式
工厂模式,抽象工厂简单工厂,
装饰器,依赖注释
观察者模式(发布订阅者模式)
适配器模式
new
async await
gennerter
迭代器的
动画优化
-
通过
will-change
提前告知浏览器某个属性会发生变化,优化性能 eg: will-change: transform; -
使用
transform
和opacity
:避免使用影响布局的属性(如width
、height
、top
、left
)进行动画,改用transform
和opacity
,它们不会触发浏览器的重排(Reflow)或重绘(Repaint),而是能够由 GPU 加速执行。 -
使用
requestAnimationFrame
:代替传统的setTimeout
或setInterval
,在每一帧中执行动画,确保与浏览器的渲染同步,减少卡顿。 -
减少不必要的动画:优化动画的应用,避免过多或不必要的动画影响性能。
-
合理使用硬件加速 :通过
translate3d
、scale3d
等启用硬件加速,改善性能。
浏览器渲染原理
XSS和CSRF
XSS本质:把用户输入当成代码执行
发生类型:存储型,反射型,dom型
处理办法:csp,输入输出转译,http-only,不使用服务端渲染或服务端返回
CSRF本质:跨站请求伪造攻击,
CSRF-Token、SameSite、Secure、Origin 头校验、双重 Cookie
AJAX与Fetch和Axios的区别
主要区别与特点
-
语法与代码简洁度
- AJAX 使用回调函数,嵌套多时容易形成"回调地狱"。
- Fetch 使用 Promise,支持链式调用和
async/await
,语法更简洁。 - Axios 基于 Promise,进一步封装,写法最短。
-
数据处理方式
- AJAX:返回的是字符串,通常要手动
JSON.parse()
。 - Fetch:提供
.json()
方法,稍微方便一些,但仍需显式调用。 - Axios:自动把响应转换为 JSON(如果是 JSON 格式),几乎不用手动处理。
- AJAX:返回的是字符串,通常要手动
-
错误处理机制
- AJAX:需要开发者自己检查
xhr.status
来判断成功与否。 - Fetch:默认只在网络错误时抛出异常,如果服务器返回 404/500,依然算作成功响应,需手动检查
response.ok
。 - Axios:自动把 HTTP 错误(如 404、500)抛出,错误处理更自然。
- AJAX:需要开发者自己检查
-
高级功能支持
-
拦截器:只有 Axios 内置,能在请求/响应前统一处理,比如在请求头加 token。
-
取消请求 :XHR 有
abort()
;Fetch 要用AbortController
;Axios 内置支持CancelToken
或AbortController
。 -
上传/下载进度:XHR 和 Axios 支持进度监听,Fetch 不支持。
-
跨域处理:
- XHR 需设置
withCredentials
。 - Fetch 要配置
credentials: 'include'
。 - Axios 默认会自动携带 Cookie,使用更方便。
- XHR 需设置
-
-
兼容性
- AJAX:所有浏览器都支持,包括旧版 IE。
- Fetch:仅现代浏览器支持,不兼容 IE。
- Axios:通过内部封装,兼容性较好,也能在 Node.js、React Native 中使用。