JavaScript 的个人总结和理解

JavaScript 深入解析

一、Promise 相关

1. then 方法的行为

  • 两个参数.then(onFulfilled, onRejected)
    • onFulfilled:Promise 状态变为 fulfilled 时执行
    • onRejected:Promise 状态变为 rejected 时执行
  • 重要特性:若 onRejected 函数捕获了 rejection,后续的 .catch() 将无法捕获同一个错误。

2. 参数非函数的处理

  • 当任一参数不是函数时,该参数会被忽略
  • onFulfilled 不是函数,会导致 resolve 的值透传到后续的 .then()
  • onRejected 不是函数,会导致 reject 的原因透传到后续的 .catch()

3. Resolve 与 Reject 的执行时机

  • resolve()reject() 方法是同步执行
  • 调用后立即改变 Promise 状态,并将对应的回调函数放入微任务队列
  • 后续的 .then().catch() 会在当前同步代码执行完毕后执行

4. catch 方法的本质

  • 语法糖catch(onRejected) 等同于 then(null, onRejected)
  • 错误传递:若 onRejected 函数中抛出新的错误,会被后续的 .catch() 捕获

5. Promise 构造函数

  • 接收一个执行器函数作为参数:new Promise((resolve, reject) => { ... })
  • 只有调用 resolve()reject() 才能改变 Promise 状态
  • 若不调用,Promise 将永远处于 pending 状态

6. await 的行为

  • await 表达式会暂停 async 函数的执行
  • 等待 Promise 完成后,将后续代码包装为微任务继续执行
  • 即使 await 的是一个非 Promise 值,后续代码也会作为微任务执行

7. async 函数的错误处理

  • 内部抛出错误或 Promise 被 reject 会暂停函数执行
  • 错误会沿着调用链向上查找 catch
  • 若被捕获,继续执行 catch 后的代码
  • 若未被捕获,会导致 async 函数返回一个 rejected 的 Promise

8. finally 方法

  • 无论 Promise 结果是 fulfilled 还是 rejected 都会执行
  • 无参数:回调函数不接收任何参数
  • 同步执行:是 Promise 链的一部分
  • 返回一个新的 Promise,继承原 Promise 的状态(除非在 finally 中抛出错误)

二、JavaScript 作用域

1. 作用域类型

  • 全局作用域:在函数和代码块之外声明的变量
  • 函数作用域:在函数内部声明的变量(var 声明的变量属于函数作用域)
  • 块级作用域:ES6 引入,由 { } 界定(letconst 声明的变量)
  • 箭头函数:没有自己的作用域,继承最近的外层作用域

2. 词法作用域(静态作用域)

  • 变量查找基于代码定义时的位置,而非运行时
  • 当前作用域找不到变量时,会向上级作用域逐层查找
  • 与函数如何调用无关

3. this 指向规则

  • 普通函数:取决于调用时的上下文
    • 直接调用:非严格模式下指向 window,严格模式下为 undefined
    • 对象方法调用:指向调用该方法的对象
    • 构造函数调用:指向新创建的对象
  • 箭头函数:继承定义时最近外层作用域的 this,且不可更改

4. 变量访问规则

  • 访问未声明的变量:抛出 ReferenceError
  • 访问对象不存在的属性:返回 undefined
  • 未使用关键字声明变量(非严格模式):自动成为全局变量

5. 作用域链

  • 函数声明时,其作用域链就已经确定
  • 包含函数自身作用域和所有外层作用域
  • 变量查找沿作用域链向上进行

6. 严格模式的影响

  • 启用严格模式:"use strict"
  • 阻止自动创建全局变量
  • 禁止删除不可删除的属性
  • 函数参数名不能重复
  • this 在全局作用域中为 undefined(而非 window

三、原型与原型链

1. 原型基本概念

  • __proto__:对象的隐式原型,指向其构造函数的 prototype
  • prototype:函数的显式原型,用于构建实例的原型对象
  • 关系实例.__proto__ === 构造函数.prototype

2. 原型链查找机制

  • 访问对象属性时,先查找自身属性
  • 若不存在,则通过 __proto__原型链上层查找
  • 直到找到属性或到达原型链终点(Object.prototype.__proto__null

3. 原型链终点

  • 所有原型链的终点是 Object.prototype
  • Object.prototype.__proto__ === null
  • 示例:String.prototype.__proto__ === Object.prototype

4. constructor 属性

  • 原型对象有一个 constructor 属性,指向其构造函数
  • 示例:实例.constructor === 构造函数
  • 构造函数.prototype.constructor === 构造函数

5. 类型判断方法

  • instanceof:检查构造函数的 prototype 是否在对象的原型链上
  • typeof:返回基本类型的字符串表示
    • 注意:typeof null === 'object'(历史遗留问题)
    • 函数返回 'function'
  • Object.prototype.toString.call():获取精确类型信息

6. 基本类型的特殊行为

  • 基本类型(stringnumberboolean)本身没有属性
  • 访问其属性时,JavaScript 会自动创建临时包装对象
  • 包装对象继承对应构造函数的 prototype 上的方法
  • 访问完成后包装对象被销毁

7. 原型链示意图

实例对象
    ↓ __proto__
构造函数.prototype
    ↓ __proto__
Object.prototype
    ↓ __proto__
null

8. 修改原型的影响

  • 修改构造函数的 prototype 会影响所有已创建和将创建的实例
  • 修改实例的 __proto__ 会改变其原型链(不推荐)
  • 最佳实践:通过 Object.create() 创建具有指定原型的新对象

总结要点

Promise 核心

  • Promise 状态不可逆,then/catch 返回新 Promise
  • 微任务优先级高于宏任务
  • async/await 是基于 Promise 的语法糖

作用域关键

  • 词法作用域决定变量查找
  • 闭包是函数和其词法环境的组合
  • this 的动态绑定是常见困惑点

原型链本质

  • JavaScript 基于原型的继承机制
  • 所有对象(除 null)都有原型
  • 原型链是实现继承和共享属性的基础
posted @ 2025-12-26 15:29  Allis  阅读(1)  评论(0)    收藏  举报