← 返回目录

第 1 卷

第 1 / 8 卷日期:

手写JavaScript核心内置方法与Promise实现

你需要手写 new、 call、 apply、 bind 操作符/函数以及简易版Promise,下面我将逐一提供完整可运行的实现代码,并附带核心原理说明。

一、手写new操作符

核心原理

  1. 创建一个新的空对象,该对象的原型会指向构造函数的 prototype 属性
  2. 将构造函数的 this 绑定到这个新创建的对象上
  3. 执行构造函数的代码(为新对象添加属性和方法)
  4. 判断构造函数的返回值:若返回值是引用类型(对象/函数等),则返回该引用类型;否则返回新创

建的对象

实现代码

Code block

1function myNew(constructor, ...args) {

2// 1.创建空对象,且让该对象的__proto__指向构造函数的prototype
3const newObj = Object.create(constructor.prototype);
4// 2.绑定this,执行构造函数
5const result = constructor.apply(newObj, args);
6// 3.判断返回值,返回对应结果
7return (typeof result === 'object' && result !== null) || typeof result

=== 'function' 8? result

9: newObj;

10} 11

12// 测试示例 13function Person(name, age) {

14this.name = name;

15this.age = age;

16this.sayHi = function() { 17console.log(`我是${this.name},今年${this.age}岁`);

二、手写call函数

核心原理

1.call 的作用是改变函数的this指向,并立即执行该函数

  1. 为目标上下文(要绑定的this)添加一个临时方法,该方法指向当前函数
  2. 执行这个临时方法,并传入后续参数
  3. 删除临时方法,避免污染目标上下文
  4. 返回函数执行的结果

实现代码

Code block

1Function.prototype.myCall = function(context, ...args) { 2// 1. 处理默认this:若context为null/undefined,默认绑定全局对象(浏览器:window,

Node:globalThis)

3const ctx = context || globalThis;
4// 2.创建唯一临时属性,避免覆盖ctx原有属性
5const tempFnKey = Symbol('tempFn');
6// 3.将当前函数(this,因为myCall是函数原型方法,this指向调用者函数)挂载到ctx上
7ctx[tempFnKey] = this;
8// 4.执行临时方法,传入参数
9const result = ctx[tempFnKey](...args);
10// 5.删除临时方法,清理环境
11delete ctx[tempFnKey];
12// 6.返回函数执行结果
13return result;
14 };

15 16// 测试示例

17const obj = { name: '李四' };

18function fn(a, b) {

19console.log(`this.name:${this.name},参数:${a} + ${b} = ${a + b}`);
20return a + b;
22//使用手写myCall
23const res1 = fn.myCall(obj, 10, 20);

三、手写apply函数

核心原理

1.apply 与 call 功能一致,唯一区别是参数传递形式: apply 的后续参数是一个数组(或类数组)

  1. 其余逻辑与 call 一致:绑定this、临时挂载函数、执行并清理、返回结果

实现代码

Code block

1Function.prototype.myApply = function(context, argsArr) { 2// 1. 处理默认this

3const ctx = context || globalThis;
4// 2.处理参数:若未传入argsArr,默认是空数组
5const args = Array.isArray(argsArr) ? argsArr : [];
6// 3.创建唯一临时属性
7const tempFnKey = Symbol('tempFn');
8// 4.挂载当前函数到ctx
9ctx[tempFnKey] = this;
10// 5.执行临时方法,展开数组参数
11const result = ctx[tempFnKey](...args);
12// 6.删除临时方法
13delete ctx[tempFnKey];
14// 7.返回执行结果
15return result;
16 };

17 18// 测试示例

19const obj2 = { name: '王五' };

20function fn2(a, b) {

21console.log(`this.name:${this.name},参数:${a} * ${b} = ${a * b}`);
22return a * b;
23}
24//使用手写myApply
25const res2 = fn2.myApply(obj2, [10, 20]);
26//输出:this.name:王五,参数:10 * 20 = 200
27console.log(res2);// 200

四、手写bind函数

核心原理

全站分卷索引 · 8 卷
  1. 1第 1 卷
  2. 2第 2 卷
  3. 3第 3 卷
  4. 4第 4 卷
  5. 5第 5 卷
  6. 6第 6 卷
  7. 7第 7 卷
  8. 8第 8 卷