1. 闭包
在函数内部定义的函数,可以访问改函数的属性和方法
私有属性 延长变量的生命周期,更好的避免命名冲突
缺点:内存消耗比较大,不建议频繁使用
2. js 原型 原型链
访问对像的属性方法,不光会在对象上查找还会在原型上查找 每个对象都有一个原型对象
指向构造函数的原型protoType
原型对象也存在原型,类推一级一级给上查找,形成了原型链
Person 实例对象 p1
p1.proto === Person.prototype
Person.prototype.proto === Object.prototype
Object.prototype.proto === null
Object.proto === Function.prototype
3. js 继承
不使用Object.create()
原型链 child.prototype = new Parents() 指向同一内存地址互相影响
构造函数 function child(){Parents.call(this)} 只能反问函数内部定义的属性方法 不是完整的原型链
组合 1+2 调用两次方法 影响性能
使用Object.create()
原型式 内存地址互相影响
寄生 不能继承原型是上的方法
整体组合 类似 ES6 新增的 extends
4. this
箭头函数的this 在创建时候已经确认了
绑定方式
默认 没有其他规则 this 默认指向全局对象(除严格模式下)
隐式绑定是指通过对象调用函数时,this 指向调用该函数的对象。
new 绑定是指通过 new 关键字来创建一个新对象时,this 指向新创建的对象。
显示(apply bind call ) call 返回的函数 列表
this在不同上下文 指向不同属性方法
apply call bind 的区别
三者都是用于显示的改变this指向的
第一个参数表示this指向的对象,若为空/null 则指向windows
第二个参数 apply 以数组形式传递,call 以参数列表的形式传递 两者都只能一次传递 bind可以多次传递
apply call 都是立即执行 (一次性修改)bind 返回修改this后的函数,需要手动执行(永久修改)
javascriptfunction test(...args){ console.log(...args) console.log(this.name,this.age); } const _obj = { name:'lili', age:18 } test.apply(_obj,[1,2,3]) test.call(_obj,1,2,3) const newFun = test.bind(_obj,1) newFun(2,3)
5. instanceof typeof 区别
instanceof(实例是否属于 对象 没法准确判断基本数据类型) typeof (基本数据类型 不能区分数组和对象)
可以使用Object.prototype.toString.call() 判断
6.new 操作符干了什么(new 操作符用于创建构造函数的实例对象)
1.创新一个新的对像
2.把对象的原型绑定到构造函数的原型
3.将构造函数中的 this
绑定到新创建的对象
- 构造函数没有return ,则返回新对象
手写 new 操作符
7. 执行上下文
执行上下文: 代码运行时所在的环境
全局 ,函数 ,eval Eval 函数执行时会创建一个 eval 执行上下文
创建阶段 (变量方法 this 作用域链) 词法环境 提供变量函数声明(静态) ,变量环境根据这些信息存储管理值 =>
执行阶段 代码执行 =>
回收 执行上下文出栈
执行栈 先进后出
8.事件
事件:用户和网页交互的结果
事件流:事件在页面传递顺序
三个阶段
捕获阶段 (从大到小) -》目标阶段-》冒泡阶段 (小小到大
事件模型:定义如何处理事件
DOM Level 0 和 DOM Level 2 是两种主要的事件模型。
直接在标签上添加On-Event 例如OnClick 不能移除 不能重复使用
利用 addEventListener('click',()=>{}) 一次添加定多个事件处理程序
事件代理
把一个/或一组响应事件委托给另一个事件 (在冒泡阶段),真正绑定的是父元素
场景 : 监听多个li变化,把事件绑定在ul上
优点:动态绑定减少工作量,减少整个页面所需内存,提高效率
避免对鼠标移动绑定,需要计算详细位置,消耗更大 focus blur 没有冒泡机制,不能代理
事件循环
eventLoop 调用栈 等待队列
- 事件循环启动:事件循环开始运行,监听各种事件。
- 同步任务执行:事件循环从执行栈中取出同步任务并执行。
- 异步任务发起:当遇到异步操作(如I/O请求、定时器等)时,程序会立即返回,不会阻塞。
- 异步任务完成:异步操作完成后,其回调函数被放入等待队列。
- 事件循环处理等待队列:事件循环不断地从等待队列中取出回调函数,并将其压入执行栈中执行。
- 循环往复:事件循环不断重复上述过程,确保所有事件和任务得到及时处理
微任务 promise async await(await 后面的代码会被阻塞)
宏任务 定时器 网络请求 用户操作 I/O请求
9.正则表达式
用来匹配字符串
方法1: /\d+/g ;
方法2: regExp();
10.内存泄漏
程序在运行过程中,未能正确释放不在使用的内存,占用内存不断增加,导致程序崩溃
垃圾回收机制
标记清除(查找上下文有引用的标记1 清除没有标记的)
引用计数(一个值引用次数为0就表示不在引用 循环引用会意外放过,引用次数不会为0)
导致内存泄漏
1.直接进行dom操作 2.定时器和回调函数
3.监听事件 4.全局变量
5.闭包 6.循环引用
避免内存泄漏
1.使用let const 定义变量,避免使用全局变量
2.监听事件需要添加取消监听的操作
3.及时的清理定时器
4.尽量避免循环引用
5.即时清理闭包
6.尽量避免dom操作
10.存储方式(cookie sessionStorage localStorage indexedDB)
cookie 存储小片段(不超过4k) 设置有效时间 组成:Name value 其他控制cookie有效期 安全性的属性
document.cookie = 'hello=123' 删除给cookie 设置过期时间
sessionStorage 对话结束 (页面关闭)清除 5M setItem() getItem() removeItem() clear() key()
缺点: 只能存入字符串不能存入对像,无法设置过期时间
localStorage 持久化本地存储 不删除永久存储 (本质是对字符串读取) 5M setItem() getItem() removeItem() clear() key()
区别:存储时间 存储大小 数据存储(cookie 传递到服务器端 服务端也可以写到cookie) localStorage sessionStorage 本地存储
indexedDB() 低级的API 存储大量结构化数据
优点:没有存储上限 异步的 比localstorage 性能更高 数据库可以做的事都可以做
缺点: 操作复杂
操作: 打开数据库开始事物 -> 创建 Object store -> 构建请求执行数据库操作 -> 通过监听正确类型dom确保请求完成 ->在结果上进行操作
使用场景:
sessionStorage 存储一些一次性登录账号
localStorage 存储一些令牌
cookie 标记用户跟踪用户行为
indexedDB 在线文档
11.函数式编程的理解
编程范型的一种(声明 命令 函数) 注重结果不注重过程
纯函数: 输入确定的值 返回确定的值 不影响全局变量
高阶函数: 以函数作为参数或者返回值
函数柯里化:把多个参数的函数,转化为嵌套的单参数函数
javascript
function Add(a,b,c){
return a+b+c
}
function addA(a){
return function(b){
return function(c){
return a+b+c
}
}
}
Add(1,2,3)
addA(1)(2)(3)
优点: 让函数更纯 每次接受一个参数 松散解耦 懒惰执行
组合函数(从右到左执行)管道函数(从左到右)把单个函数组合起来
函数式编程的优点:
1.确定的输入输出,不影响其他范围的变量,无副作用
2.把多个函数进行组成,增加复用性
3.简少代码量便于维护
4.宗旨是无状态,更少的状态减 少出错
缺点:
1.开销大(对函数过度包装)
2.占用资源(为了不更改状态 创建新函数 垃圾回收机制压力大)
3.递归陷阱 (实现迭代)
12.函数缓存
把函数的计算结果进行缓存
1.实现方式:
闭包
柯里化
高阶函数
待补充:
丢失精度怎么解决(借助第三方工具 , 设置精度范围 bigint)
防抖节流
判断元素是否在可视区域
上拉加载 下拉刷新
断点续传(分成大小相等的片,带标识 上传完成整合)
单点登录(设置令牌)
常见攻击方式
xss sql注入