JavaScript 中的 Promise 与原型链详解
在 JavaScript 中,Promise 和原型链是两个核心概念。Promise 为异步编程提供了优雅的解决方案,而原型链则是 JavaScript 实现面向对象编程的基础。本文将结合具体代码示例,详细解析这两个概念。
一、Promise:异步编程的利器
Promise 是 ES6 引入的异步编程解决方案,它可以有效解决回调地狱问题,让异步代码的逻辑更清晰。
1. Promise 的基本概念
- 状态:Promise 有三种状态,分别是
pending(等待中)、fulfilled(已成功)、rejected(已失败)。状态一旦改变就不可逆。 - ** executor 函数 **:创建 Promise 实例时传入的函数,会立即执行,用于定义异步操作。
- 方法:
then()(处理成功状态)、catch()(处理失败状态)、finally()(无论成功失败都会执行)。
2. Promise 代码解析
以下是 Promise 的示例代码及详细解释:
<script>
// 创建Promise实例p
const p = new Promise((resolve, reject) => {
// executor函数会立即执行
console.log(111); // 立即打印111
// 模拟异步耗时任务(1秒后执行)
setTimeout(() => {
console.log(333); // 1秒后打印333
reject('错误1'); // 将状态改为rejected,传递错误信息
// resolve('结果1'); // 若调用此句,状态改为fulfilled,传递成功结果
}, 1000);
})
console.log(222); // 打印222(在setTimeout之前执行,因为setTimeout是异步)
console.log(p,'////'); // 打印Promise实例(此时状态为pending)
console.log(p.__proto__ == Promise.prototype); // 打印true(实例的__proto__指向构造函数的prototype)
console.log(p.__proto__); // 打印Promise的原型对象
// 处理Promise结果(异步执行)
p.then((data) => {
// 当状态为fulfilled时执行,接收resolve传递的数据
console.log(data);
}).catch(err => {
// 当状态为rejected时执行,接收reject传递的错误
console.log(err); // 此处会打印'result1'
}).finally(() => {
// 无论成功失败都会执行
console.log('finally'); // 打印'finally'
})
</script>
执行顺序说明:
- 执行
new Promise时,立即调用 executor 函数,打印111 - 遇到
setTimeout,将其回调放入异步队列,继续执行同步代码 - 打印
222和 Promise 实例(此时状态为pending) - 1 秒后,执行
setTimeout回调:打印333,调用reject将状态改为rejected - 触发
catch方法,打印错误1 - 最后执行
finally,打印finally
二、原型链:JavaScript 面向对象的基石
JavaScript 的面向对象并非基于类的血缘关系,而是通过原型链实现的。每个对象都有__proto__属性,指向其原型对象;构造函数有prototype属性,也指向原型对象;原型对象的constructor属性指向构造函数。
1. 原型链代码解析
以下是原型链的示例代码及解释:
// 定义构造函数Person
function Person(name, age) {
this.name = name; // 实例属性name
this.age = age; // 实例属性age
}
// 给Person的原型对象添加属性species
Person.prototype.species = '人类';
// 创建Person实例zhen
let zhen = new Person('郑总', 18);
console.log(zhen.species); // 打印'人类'(通过原型链访问到Person.prototype上的species)
// 定义一个普通对象kong
const kong = {
name: '孔子',
hobbies: ['读书', '喝酒']
}
// 修改zhen的__proto__指向kong(改变原型链)
zhen.__proto__ = kong;
// 此时zhen的原型链指向kong,而非Person.prototype
console.log(zhen.hobbies); // 打印['读书', '喝酒'](访问kong的hobbies)
console.log(zhen.species); // 打印undefined(kong上没有species属性,且原型链中也没有)
原型链查找规则:
- 当访问对象的属性时,先在对象自身查找,若找不到则通过
__proto__查找原型对象 - 若原型对象中也没有,则继续查找原型对象的
__proto__,直到null - 上例中,修改
zhen.__proto__ = kong后,原型链指向改变,因此无法再访问Person.prototype上的species
三、总结
-
Promise:
- 是 ES6 的异步解决方案,通过状态管理简化异步逻辑
- 核心是
pending→fulfilled/rejected的状态变化,以及then/catch/finally的链式调用
-
原型链:
- JavaScript 面向对象的基础,通过
__proto__串联对象与原型 - 实例的
__proto__指向构造函数的prototype,原型对象的constructor指向构造函数
- JavaScript 面向对象的基础,通过