JS千锤百炼
数据类型
基础类型
字符串
Number
二进制
小数
使用浮点数表示法(如 IEEE 754),包含符号位、指数位和尾数位。
转换方法
- 整数部分:不断除以
2
,记录余数。 - 小数部分:不断乘以
2
,记录整数部分。
示例
将 6.25
转换为二进制
- 整数部分(6):
6 / 2 = 3
,余数0
3 / 2 = 1
,余数1
1 / 2 = 0
,余数1
- 逆序排列:
110
- 小数部分(0.25) :
0.25 * 2 = 0.5
,整数部分0
0.5 * 2 = 1.0
,整数部分1
- 顺序排列:
.01
- 合并结果 :
110.01
负数
在二进制中以补码来表示
- 计算出负数绝对值对应的正数,例如-6绝对值是6,二进制 00000110
- 将该正数取反得到补码,如上 00000110 取反,11111001
- +1 得到的结果就是表示负数的补码,如上 11111001 + 1 = 11111010
补码特性
- 符号位 :最高位(最左边的位)是符号位:
0
表示正数。1
表示负数。- 范围 :对于
n
位二进制数,补码表示的范围是: - 最小值:
-2^(n-1)
- 最大值:
2^(n-1) - 1
- 例如,8 位补码的范围是
-128
到127
。 - 唯一性 :每个数只有一个补码表示,避免了正负零的问题。
位运算
暂时无法在飞书文档外展示此内容
Number高频题
0.1 + 0.2 === 0.3?
暂时无法在飞书文档外展示此内容
对象
原型
[[prototype]]写作__proto__,也可以通过Object.getPrototypeOf获取,他指向他的构造函数对象的prototype属性
new命令
暂时无法在飞书文档外展示此内容
this
instanceof
继承
构造函数继承
Tips: 多继承可以借 Object.assign(Sub.prototype, Super2.prototype)变向实现
暂时无法在飞书文档外展示此内容
对象高频题
属性自定义
Object.defineProperty
:适合对单个属性进行精细控制,例如定义 getter/setter 或修改属性特性。Proxy
:适合拦截整个对象的操作,自定义对象的行为。Reflect.defineProperty
:与Object.defineProperty
功能相同,但返回布尔值,适合需要判断操作是否成功的场景。
对象遍历
遍历方法 | 描述 | 自身属性 | 原型属性 |
---|---|---|---|
可枚举 | 不可枚举 | Symbol | 可枚举 |
for...in | 遍历属性 | ✅ | ❌ |
Object.keys | 获取自身属性 | ✅ | ❌ |
Object.values | 获取自身属性值 | ✅ | ❌ |
Object.entries | 获取自身属性+值 [[key, value]] | ✅ | ❌ |
Object.getOwnPropertyNames | 获取自身属性名 | ✅ | ✅ |
Object.getOwnPropertySymbols | 获取自身Symbol属性 | ❌ | ❌ |
Reflect.ownKeys | 获取自身所有属性 | ✅ | ✅ |
暂时无法在飞书文档外展示此内容
数组
Api
Sort
暂时无法在飞书文档外展示此内容
类型高频考题
typeof和instanceof
valueOf和toString
二者都是Object原型链上的方法,当进行拼接或运算时,可能会触发隐式转换,先调用valueOf,如果valueOf不是能拿来运算的原始值,就会继续调用toString。
valueOf
暂时无法在飞书文档外展示此内容
toString
暂时无法在飞书文档外展示此内容
valueEqual等值判断
暂时无法在飞书文档外展示此内容
函数
Prototype
函数对象具有prototype原型对象属性,用于定义通过new操作符创建的实例原型,prototype.constructor指向构造函数本身。
Object.prototype
所有对象的原型链终点,所有对象都继承Object.prototype对象的方法和属性(除了Object.create(null))
暂时无法在飞书文档外展示此内容
Function.prototype
所有函数对象的原型,所以有以下有趣的自循环原型关系:
暂时无法在飞书文档外展示此内容
eval
将字符串当作js执行的函数,常用来动态创建js执行,有安全隐患,创建函数建议用new Function,解析JSON用JSON.parse。
非严格模式,运行作用域为调用eval所在作用域;严格模式,作用域会eval内部临时作用域;
暂时无法在飞书文档外展示此内容
箭头函数和普通函数区别
箭头函数
this指向词法作用域,函数定义时的作用域this指向
普通函数
this指向动态作用域,函数被调用时的上下文this指向
函数高频考题
节流防抖
暂时无法在飞书文档外展示此内容
ES6+
模块
类
extends
暂时无法在飞书文档外展示此内容
super
手写super
Set/WeakSet
Map/WeakMap
Symbol
Proxy
ES6+高频考题
... 拓展运算符兼容写法
暂时无法在飞书文档外展示此内容
异步
Promise
Async await
迭代器
运行时
垃圾回收
JS采用分代式垃圾回收机制,内存分为新老生代空间
新生代空间
存放短期数据,采用 Scavenge GC算法(复制算法) ,有From和To两个空间。
新分配的对象放From空间,当From空间满时,进行GC处理,将存活对象复制到To空间,销毁失活对象,然后将To空间与From空间互换
老生代空间
存放长期活跃数据,有两个算法,标记清除算法和 标记压缩算法 。
如何进入老生代
- 经历过新生代GC的对象会进入老生代空间
- 在To空间内存占用超过25%的对象
标记清除法
标记:从根对象遍历,即全局对象或当前调用栈变量开始,遍历所有可触达对象,将其标记为活跃。
清除:遍历堆内存,清除回收所有未标记的对象(为优化回收造成的页面停顿,后续升级了增量标记和并发标记)
标记压缩法
也叫标记整理法,标记清除后形成碎片空间,当碎片过多会触发整理,将活跃对象往一端迁移聚集,然后清除回收空闲空间
优化内存使用
- 避免全局变量
- 及时释放引用,如设置null,清定时器事件监听
- 使用弱引用(WeakSet和WeakMap)存放临时数据
作用域
闭包
模块
正则
媒体
文件上传
事件
传播三阶段
- 捕获阶段: window-document-html-body-父节点-目标节点
- 目标阶段:目标节点触发事件
- 冒泡阶段:目标节点-父节点-body-html-document-window
事件API
addEventListener
暂时无法在飞书文档外展示此内容
Event和CustomEvent
暂时无法在飞书文档外展示此内容
dispatchEvent
EventTarget.dispatchEvent,只要有preventDefault则返回false
StopImmediatePropagation
除了阻止向上冒泡,同时阻止了当前节点相同事件的其他函数(同一个事件可以添加多个处理函数按顺序执行)
网页
session历史
pageshow pagehide
当用户点击“前进/后退”按钮时,浏览器就会从缓存中加载页面。
pageshow
事件在页面加载时触发,包括第一次加载和从缓存加载两种情况,第一次加载时,它的触发顺序排在 load
事件后面。从缓存加载时,load
事件不会触发。
pageshow
的 persisted
,页面第一次加载时,是 false
;从缓存加载时,是 true
。
pagehide
事件,当用户通过“前进/后退”按钮,离开当前页面时触发。如果定义了 unload/beforeunload
事件页面不会保存在缓存中,用 pagehide
事件,页面会保存在缓存中。
pagehide
的 persisted
,true
表示页面要保存在缓存中;false
表示网页不保存在缓存中,如果监听了unload事件,该函数将在 pagehide 事件后立即运行。
hashchange popstate
调用 history.pushState()
或 history.replaceState()
,并不会触发 popstate
事件。该事件只在用户在 history
记录之间显式切换时触发,比如鼠标点击“后退/前进”按钮,或者在脚本中调用 history.back()
、history.forward()
、history.go()
时触发。
网页状态
DOMContentLoaded
仅完成了DOM,其他样式资源可能未完成,load事件才是完全加载完成
readystatechange
readystatechange
事件当 Document 对象和 XMLHttpRequest 对象的 readyState
属性发生变化时触发。document.readyState
有三个可能的值:
loading
(网页正在加载)interactive
(网页已经解析完成,但是外部资源仍然处在加载状态)complete
(网页和所有外部资源已经结束加载,load
事件即将触发)
暂时无法在飞书文档外展示此内容
拖拽
暂时无法在飞书文档外展示此内容