第 2 卷
- 新函数的原型要指向原函数的原型,保证原型链继承
实现代码
Code block
1Function.prototype.myBind = function(context, ...bindArgs) {
| 2 | const _this = this;//保存原函数的引用 |
|---|---|
| 3 | // 1.返回一个新的绑定函数 |
| 4 | const boundFn = function(...callArgs) { |
| 5 | // 2.判断是否通过new调用:若通过new调用,this指向实例;否则指向传入的context |
| 6 | const isNewCall = this instanceof boundFn; |
| 7 | const ctx = isNewCall ? this : context || globalThis; |
| 8 | // 3.合并绑定阶段参数和调用阶段参数,执行原函数并返回结果 |
| 9 | return _this.apply(ctx, [...bindArgs, ...callArgs]); |
| 10 | }; |
| 11 | // 4.让新函数的原型指向原函数的原型,保证原型链继承 |
| 12 | boundFn.prototype = Object.create(_this.prototype); |
| 13 | // 5.修正构造函数指向 |
| 14 | boundFn.prototype.constructor = _this; |
| 15 | return boundFn; |
| 16 }; |
17 18// 测试示例
19const obj3 = { name: '赵六' };
20function fn3(a, b, c) { 21console.log(`this.name:${this.name},参数:${a} + ${b} + ${c} = ${a + b +
c}`);
22return a + b + c;
23} 24// 1. 绑定this和部分参数
| 25 | const boundFn = fn3.myBind(obj3, 10); |
|---|---|
| 26 | // 2.调用新函数,传入剩余参数(柯里化) |
| 27 | const res3 = boundFn(20, 30); |
| 28 | //输出:this.name:赵六,参数:10 + 20 + 30 = 60 |
| 29 | console.log(res3);// 60 |
30 31// 3. 测试new调用绑定函数
32function Person2(name) { 33this.name = name;
35const boundPerson = Person2.myBind({ name: '默认名' });
五、手写简易版Promise
核心原理
- Promise有三种状态: pending(等待中)、 fulfilled(成功)、 rejected(失败),
状态一旦改变就不可逆转
- 接收一个执行器函数(executor),该函数立即执行,传入 resolve(成功回调)和 reject
(失败回调)两个参数
- 拥有 then 方法:接收 onFulfilled(成功回调)和 onRejected(失败回调)两个参数,
支持链式调用
- 异步执行: then 方法的回调会在执行器函数异步操作完成后执行
- 值的穿透:若 then 方法未传入合法回调,会将结果透传给下一个 then
实现代码
Code block
1// 定义Promise状态常量 2const PENDING = 'pending';
3const FULFILLED = 'fulfilled';
4const REJECTED = 'rejected';
5 6class MyPromise {
7constructor(executor) { 8try {
| 9 | // 1.初始化状态、成功值、失败原因 |
|---|---|
| 10 | this.status = PENDING; |
| 11 | this.value = undefined;//成功时的返回值 |
| 12 | this.reason = undefined;//失败时的原因 |
| 13 | // 2.存储异步回调(当then方法在状态改变前调用时,缓存回调函数) |
| 14 | this.onFulfilledCallbacks = []; |
| 15 | this.onRejectedCallbacks = []; |
16
| 17 | // 3.定义resolve函数:将状态改为成功,保存成功值,执行缓存的成功回调 |
|---|---|
| 18 | const resolve = (value) => { |
| 19 | //状态不可逆转:只有pending状态才能改变 |
| 20 | if (this.status === PENDING) { |
| 21 | this.status = FULFILLED; |
| 22 | this.value = value; |
| 28 | // 4.定义reject函数:将状态改为失败,保存失败原因,执行缓存的失败回调 |
|---|---|
| 29 | const reject = (reason) => { |
| 30 | if (this.status === PENDING) { |
| 31 | this.status = REJECTED; |
| 32 | this.reason = reason; |
| 33 | //批量执行缓存的失败回调 |
| 34 | this.onRejectedCallbacks.forEach(cb => cb()); |
| 35 | } |
| 36 | }; |
37 38// 5. 立即执行执行器函数
| 39 | executor(resolve, reject); |
|---|---|
| 40 | } catch (error) { |
| 41 | // 6.执行器函数报错时,直接调用reject |
| 42 | reject(error); |
| 43 | } |
| 44 | } |
45 46// 实现then方法
47then(onFulfilled, onRejected) { 48// 处理值的穿透:默认回调函数透传结果/原因
49onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
50onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason; };
51 52// 7. 返回新的Promise,支持链式调用
53return new MyPromise((resolve, reject) => { 54// 处理成功状态
55if (this.status === FULFILLED) {
| 56 | //异步执行回调(模拟原生Promise的微任务执行) |
|---|---|
| 57 | setTimeout(() => { |
| 58 | try { |
| 59 | const result = onFulfilled(this.value); |
| 60 | //处理回调返回值:若返回MyPromise实例,等待其状态改变;否则 |
直接resolve 61result instanceof MyPromise ? result.then(resolve,
reject) : resolve(result);
62} catch (error) { 63reject(error);
65}, 0);