文章目录一、原型与原型链1. 基础概念2. 三大核心等式3. 原型链查找规则属性 / 方法4. 面试高频二、作用域、作用域链、闭包1. 三大作用域2. 作用域链3. 闭包三、this 指向1. 五大 this 指向规则2. 改变 this 指向call /apply/bind四、继承六种方式原型链继承借用构造函数继承组合继承原型式继承寄生式继承寄生组合继承五、JS 执行机制事件循环 EventLoop六、异步编程1. 发展历程2. Promise3. async/await七、深浅拷贝1. 浅拷贝2. 深拷贝八、防抖与节流1. 防抖 debounce2. 节流 throttle九、垃圾回收机制 GC1. 内存2. 回收算法十、ES6十一、数组高级方法十二、前端跨域十三、回流与重绘一、原型与原型链1. 基础概念构造函数用来创建对象的函数约定首字母大写。通过 new 关键字调用生成实例对象。显式原型 prototype只有函数才拥有 prototype 属性。它是一个对象用于存放所有实例共享的属性和方法。作用节省内存避免每个实例都创建重复方法。隐式原型proto所有对象实例、函数、数组都拥有proto。它指向创建该对象的构造函数的 prototype。是实现原型链的核心纽带。constructor位于原型对象上指回构造函数本身。用于判断对象的构造类型。2. 三大核心等式// 1. 实例的隐式原型 构造函数的显式原型实例对象.__proto__构造函数.prototype// 2. 原型的构造器 构造函数构造函数.prototype.constructor构造函数// 3. 原型链的顶端是 nullObject.prototype.__proto__null3. 原型链查找规则属性 / 方法当访问一个对象的属性 / 方法时先在自身查找找到直接使用。找不到通过proto去构造函数的原型上查找。继续顺着原型链向上查找直到 Object.prototype。最终找不到返回 undefined。4. 面试高频原型的作用实现方法共享、继承节省内存空间。原型链作用实现对象的继承让一个对象可以访问另一个对象的属性和方法。结论所有对象最终都继承自 Object数组、函数、日期本质上都是对象。二、作用域、作用域链、闭包1. 三大作用域全局作用域代码在任何位置都能访问。全局变量、全局函数、window 对象。函数作用域只在函数内部可访问。函数外部无法读取内部变量。块级作用域let / const 在 {} 内形成的作用域。var 没有块级作用域。2. 作用域链定义内层函数可以访问外层函数变量层层向上查找形成的链式结构。作用保证变量的有序访问。3. 闭包定义内层函数引用了外层函数的变量即使外层函数执行完毕变量也不会销毁这种现象就是闭包。形成条件1. 函数嵌套函数。2. 内部函数引用了外部函数的变量。3. 内部函数被调用 /return 出去。闭包作用1. 延长局部变量生命周期。2. 私有化变量防止全局污染。3. 可用于模块化开发、缓存数据、防抖节流。闭包缺点1. 变量常驻内存容易造成内存泄漏。2. 滥用闭包会降低代码可读性。面试手写闭包functionouter(){letnum10;// 被引用的变量returnfunctioninner(){console.log(num);// 引用外层变量};}letfnouter();fn();// 10 → 形成闭包三、this 指向1. 五大 this 指向规则普通函数调用this → window对象方法调用this → 调用它的对象构造函数调用this → new 创建的实例对象箭头函数没有自己的 this继承外层作用域的 this无法修改。事件绑定this → 触发事件的 DOM 元素2. 改变 this 指向call /apply/bindcall()立即执行函数。参数逐个传递。fn.call(thisArg,arg1,arg2)apply()立即执行函数。参数以数组传递。fn.apply(thisArg,[arg1,arg2])bind()不立即执行返回一个新函数。永久绑定 this。letnewFnfn.bind(thisArg)newFn()总结: 立即执行用call / apply 后续执行用bind四、继承六种方式原型链继承优点实现简单、共享原型方法。缺点所有实例共享引用类型属性。借用构造函数继承优点避免引用共享。缺点无法继承原型方法。组合继承结合前两者优点最常用。原型式继承浅拷贝式继承。寄生式继承在原型式基础上增加属性 / 方法。寄生组合继承最优继承无缺陷底层源码常用。ES6 class 继承工作最常用classParent{constructor(name){this.namename;}}classChildextendsParent{constructor(name,age){super(name);// 必须调用继承父类属性this.ageage;}}五、JS 执行机制事件循环 EventLoop核心特点JS 是单线程同一时间只能做一件事。为了不阻塞引入异步任务。执行顺序执行同步代码。同步执行完 → 执行所有微任务。微任务清空 → 执行一个宏任务。循环执行 → 事件循环。宏任务 vs 微任务宏任务优先级低setTimeout、setInterval、AJAX、DOM 事件、IO微任务优先级高Promise.then/catch/finally、async/await、queueMicrotask注意await 后面的代码属于微任务。六、异步编程1. 发展历程回调函数 → 回调地狱。Promise → 解决回调地狱。Generator → 分段执行。async/await → 终极方案。2. Promise三种状态pending进行中fulfilled成功rejected失败状态一旦改变不可逆转。常用 API.then() 成功.catch() 失败Promise.all() 全部成功才成功Promise.race() 谁快执行谁3. async/awaitasync 函数返回 Promise。await 暂停执行等待 Promise 结果。优点代码像同步一样简洁、易读、好调试。七、深浅拷贝1. 浅拷贝只拷贝第一层。深层对象共用地址一改全改。实现…、Object.assign、slice、concat。2. 深拷贝拷贝所有层级新旧数据完全独立。简易实现JSON.parse(JSON.stringify(obj))缺点无法拷贝函数、正则、日期、undefined。面试必考手写递归深拷贝。八、防抖与节流1. 防抖 debounce频繁触发 → 只执行最后一次。场景搜索框输入、窗口缩放。2. 节流 throttle固定时间 → 只执行一次。场景页面滚动、鼠标移动、高频点击。九、垃圾回收机制 GC1. 内存栈基本类型自动释放。堆引用类型GC 回收。2. 回收算法引用计数引用为 0 回收缺点循环引用无法回收。标记清除主流标记无用对象统一回收。内存泄漏场景1. 意外全局变量2. 闭包滥用3. 定时器未清除4. DOM 事件未解绑十、ES6let/const块级作用域、无变量提升。解构赋值快速取对象 / 数组。模板字符串${}。展开运算符 …。Set 去重、Map 任意键名。模块化 import/export。可选链 ?.、空值合并 ??。十一、数组高级方法forEach遍历无返回值。map返回新数组。filter过滤。reduce累加、统计、去重。find查找元素。every全部满足。some任一满足。十二、前端跨域跨域原因浏览器同源策略协议、域名、端口任一不同即跨域。解决方案CORS主流proxy 代理Vue/ReactJSONP仅 GETNginx 反向代理十三、回流与重绘重绘改变样式颜色、背景不改变布局。回流重排改变宽高、位置、结构重新布局。重点回流一定触发重绘重绘不一定回流。回流性能消耗极大。
js高级复习
文章目录一、原型与原型链1. 基础概念2. 三大核心等式3. 原型链查找规则属性 / 方法4. 面试高频二、作用域、作用域链、闭包1. 三大作用域2. 作用域链3. 闭包三、this 指向1. 五大 this 指向规则2. 改变 this 指向call /apply/bind四、继承六种方式原型链继承借用构造函数继承组合继承原型式继承寄生式继承寄生组合继承五、JS 执行机制事件循环 EventLoop六、异步编程1. 发展历程2. Promise3. async/await七、深浅拷贝1. 浅拷贝2. 深拷贝八、防抖与节流1. 防抖 debounce2. 节流 throttle九、垃圾回收机制 GC1. 内存2. 回收算法十、ES6十一、数组高级方法十二、前端跨域十三、回流与重绘一、原型与原型链1. 基础概念构造函数用来创建对象的函数约定首字母大写。通过 new 关键字调用生成实例对象。显式原型 prototype只有函数才拥有 prototype 属性。它是一个对象用于存放所有实例共享的属性和方法。作用节省内存避免每个实例都创建重复方法。隐式原型proto所有对象实例、函数、数组都拥有proto。它指向创建该对象的构造函数的 prototype。是实现原型链的核心纽带。constructor位于原型对象上指回构造函数本身。用于判断对象的构造类型。2. 三大核心等式// 1. 实例的隐式原型 构造函数的显式原型实例对象.__proto__构造函数.prototype// 2. 原型的构造器 构造函数构造函数.prototype.constructor构造函数// 3. 原型链的顶端是 nullObject.prototype.__proto__null3. 原型链查找规则属性 / 方法当访问一个对象的属性 / 方法时先在自身查找找到直接使用。找不到通过proto去构造函数的原型上查找。继续顺着原型链向上查找直到 Object.prototype。最终找不到返回 undefined。4. 面试高频原型的作用实现方法共享、继承节省内存空间。原型链作用实现对象的继承让一个对象可以访问另一个对象的属性和方法。结论所有对象最终都继承自 Object数组、函数、日期本质上都是对象。二、作用域、作用域链、闭包1. 三大作用域全局作用域代码在任何位置都能访问。全局变量、全局函数、window 对象。函数作用域只在函数内部可访问。函数外部无法读取内部变量。块级作用域let / const 在 {} 内形成的作用域。var 没有块级作用域。2. 作用域链定义内层函数可以访问外层函数变量层层向上查找形成的链式结构。作用保证变量的有序访问。3. 闭包定义内层函数引用了外层函数的变量即使外层函数执行完毕变量也不会销毁这种现象就是闭包。形成条件1. 函数嵌套函数。2. 内部函数引用了外部函数的变量。3. 内部函数被调用 /return 出去。闭包作用1. 延长局部变量生命周期。2. 私有化变量防止全局污染。3. 可用于模块化开发、缓存数据、防抖节流。闭包缺点1. 变量常驻内存容易造成内存泄漏。2. 滥用闭包会降低代码可读性。面试手写闭包functionouter(){letnum10;// 被引用的变量returnfunctioninner(){console.log(num);// 引用外层变量};}letfnouter();fn();// 10 → 形成闭包三、this 指向1. 五大 this 指向规则普通函数调用this → window对象方法调用this → 调用它的对象构造函数调用this → new 创建的实例对象箭头函数没有自己的 this继承外层作用域的 this无法修改。事件绑定this → 触发事件的 DOM 元素2. 改变 this 指向call /apply/bindcall()立即执行函数。参数逐个传递。fn.call(thisArg,arg1,arg2)apply()立即执行函数。参数以数组传递。fn.apply(thisArg,[arg1,arg2])bind()不立即执行返回一个新函数。永久绑定 this。letnewFnfn.bind(thisArg)newFn()总结: 立即执行用call / apply 后续执行用bind四、继承六种方式原型链继承优点实现简单、共享原型方法。缺点所有实例共享引用类型属性。借用构造函数继承优点避免引用共享。缺点无法继承原型方法。组合继承结合前两者优点最常用。原型式继承浅拷贝式继承。寄生式继承在原型式基础上增加属性 / 方法。寄生组合继承最优继承无缺陷底层源码常用。ES6 class 继承工作最常用classParent{constructor(name){this.namename;}}classChildextendsParent{constructor(name,age){super(name);// 必须调用继承父类属性this.ageage;}}五、JS 执行机制事件循环 EventLoop核心特点JS 是单线程同一时间只能做一件事。为了不阻塞引入异步任务。执行顺序执行同步代码。同步执行完 → 执行所有微任务。微任务清空 → 执行一个宏任务。循环执行 → 事件循环。宏任务 vs 微任务宏任务优先级低setTimeout、setInterval、AJAX、DOM 事件、IO微任务优先级高Promise.then/catch/finally、async/await、queueMicrotask注意await 后面的代码属于微任务。六、异步编程1. 发展历程回调函数 → 回调地狱。Promise → 解决回调地狱。Generator → 分段执行。async/await → 终极方案。2. Promise三种状态pending进行中fulfilled成功rejected失败状态一旦改变不可逆转。常用 API.then() 成功.catch() 失败Promise.all() 全部成功才成功Promise.race() 谁快执行谁3. async/awaitasync 函数返回 Promise。await 暂停执行等待 Promise 结果。优点代码像同步一样简洁、易读、好调试。七、深浅拷贝1. 浅拷贝只拷贝第一层。深层对象共用地址一改全改。实现…、Object.assign、slice、concat。2. 深拷贝拷贝所有层级新旧数据完全独立。简易实现JSON.parse(JSON.stringify(obj))缺点无法拷贝函数、正则、日期、undefined。面试必考手写递归深拷贝。八、防抖与节流1. 防抖 debounce频繁触发 → 只执行最后一次。场景搜索框输入、窗口缩放。2. 节流 throttle固定时间 → 只执行一次。场景页面滚动、鼠标移动、高频点击。九、垃圾回收机制 GC1. 内存栈基本类型自动释放。堆引用类型GC 回收。2. 回收算法引用计数引用为 0 回收缺点循环引用无法回收。标记清除主流标记无用对象统一回收。内存泄漏场景1. 意外全局变量2. 闭包滥用3. 定时器未清除4. DOM 事件未解绑十、ES6let/const块级作用域、无变量提升。解构赋值快速取对象 / 数组。模板字符串${}。展开运算符 …。Set 去重、Map 任意键名。模块化 import/export。可选链 ?.、空值合并 ??。十一、数组高级方法forEach遍历无返回值。map返回新数组。filter过滤。reduce累加、统计、去重。find查找元素。every全部满足。some任一满足。十二、前端跨域跨域原因浏览器同源策略协议、域名、端口任一不同即跨域。解决方案CORS主流proxy 代理Vue/ReactJSONP仅 GETNginx 反向代理十三、回流与重绘重绘改变样式颜色、背景不改变布局。回流重排改变宽高、位置、结构重新布局。重点回流一定触发重绘重绘不一定回流。回流性能消耗极大。