LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

手写new操作符竟如此简单 - 彻底搞懂JavaScript对象创建机制

freeflydom
2025年8月5日 9:22 本文热度 52

前言

要实现手写new,关键在于先吃透它的本质。new作为 JavaScript 中创建对象的核心操作符,看似简单的语法背后,藏着一套严谨的执行逻辑。只有先弄清楚它究竟是什么—— 是连接构造函数与实例对象的桥梁?还是激活原型链关联的开关?再明确它能完成哪些核心功能—— 是初始化对象属性,还是建立继承关系?最后拆解它的执行过程中每一步都发生了什么—— 从创建空对象到绑定原型,从执行构造函数到返回实例…… 搞懂了这些,手写new的思路才会清晰起来。接下来,我们一起来揭露这个东西

new 是什么?

new是JavaScript中用于创建对象实例的关键操作符,它是面向对象编程中对象实例化的核心机制。

我们通常利用new来实例化一个对象:

function Person(name, age) {
  this.name = name;
  this.age = age;
  this.Talk = function () {
        console.log('我是' + this.name);
    }
}
// 使用new创建实例
const person1 = new Person('张三', 25);
console.log(person1); // 输出: Person { name: '张三', age: 25 }
person1.Talk(); // 输出: 我是张三

我们可以看到利用new产生的实例继承了构造函数的属性和方法,并且成功实例化了一个对象。

new 的过程中发生了什么?

当使用new调用函数时,JavaScript引擎会执行以下步骤:

  1. 创建新对象:创建一个全新的空对象{}
  2. 链接原型:将这个新对象的[[Prototype]](即__proto__)链接到构造函数的prototype对象
  3. 绑定this:将构造函数中的this绑定到这个新对象
  4. 执行构造函数:执行构造函数中的代码(通常用于初始化对象)
  5. 返回对象:如果构造函数没有返回对象,则自动返回这个新对象

当然,对于这5条,1,3就不用说了,

1是基础步骤,我们要返回一个实例化对象,必须得初始化一个,没有米怎么蒸米饭呢?

3的话,上一期的this指向中有讲过,传送门🚪=>美丽的地方0^0~

2,我们可以在浏览器中console.log(person1),查看它的__proto__是否等于Person.prototype

4,我们也可以随便在构造函数中加一句console.log('whatever u want'),观察它是否会执行

5,重点来咯!当构造函数显式返回一个对象时,new操作符会忽略原本创建的新对象,直接返回构造函数返回的这个对象。此时新对象的属性初始化将被丢弃,只有返回对象的内容会被保留。

构造函数返回对象完整规则:

  1. 返回对象类型(包括数组、函数等)
    → 完全替代new默认创建的对象
  2. 返回原始值(数字、字符串等)
    → 被忽略,仍然返回new创建的新对象
  3. 没有return语句
    → 正常返回new创建的新对象

示例:

// 情况1:返回对象
function Case1() {
  this.a = 1;
  return { b: 2 }; // 对象优先
}
console.log(new Case1()); // { b: 2 }
// 情况2:返回原始值
function Case2() {
  this.a = 1;
  return 123; // 原始值被忽略
}
console.log(new Case2()); // { a: 1 }
// 情况3:无返回
function Case3() {
  this.a = 1;
}
console.log(new Case3()); // { a: 1 }

手写new

okk,既然我们都知道了你new出一个对象安慰自己没有对象的事实时会发生的事情了,我们开始手写一个new吧!

记住这灵魂的舞步~ :

  1. 创建新对象:创建一个全新的空对象{}
  2. 链接原型:将这个新对象的[[Prototype]](即__proto__)链接到构造函数的prototype对象
  3. 绑定this:将构造函数中的this绑定到这个新对象
  4. 执行构造函数:执行构造函数中的代码(通常用于初始化对象)
  5. 返回对象:如果构造函数没有返回对象,则自动返回这个新对象

ok,假设我们有一个构造函数Person,要利用我们的手写new创建一个实例,

那么首先我们要创建一个函数,用来实现new:

function Person(name, age) {
    this.name = name;
    this.age = age;
}
function myNew(){}

现在我们要实现创建一个新的空对象:

function myNew(){
var obj = {};
}

接下来,我们要确立原型,链接到构造函数,那么该怎么做呢?

既然我们要用到构造函数,那么我们应该至少应该拿到构造函数吧,所以我们就要把构造函数和所需要的形参传递进来!

function myNew(constructor,...args){
var obj = new Object();
}
// tips: ...args为rest运算符,负责接收其余剩下的参数

接下来我们开始绑定prototype:

function myNew(constructor,...args){
var obj = new Object();
obj.__proto__ = constructor.prototype;
// obj 继承构造函数的prototype,prototype包含 构造函数 的各种属性和方法
}

Next,开始激情♂地绑定this到新的实例对象上,那么怎么样能够将构造函数的this绑定到obj到上面呢?上一期我们学习了显式绑定,我们可以利用callapplybind方法来将其绑定到理想目标上:

function myNew(constructor,...args){
var obj = new Object();
obj.__proto__ = constructor.prototype;
constructor.bind(obj,...args);
}

这样我们就成功了,下一步就是要执行构造函数了,我们可以用一个变量接受bind的结果并执行它:

function myNew(constructor,...args){
var obj = new Object();
obj.__proto__ = constructor.prototype;
var before = constructor.bind(obj,...args);
before();
}

最后利用一个变量接受结果,判断构造函数返回的结果是否符合要求,

如果不符合则返回新对象

如果符合则返回构造函数准备好的结果

function myNew(constructor,...args){
var obj = new Object();
obj.__proto__ = constructor.prototype;
var before = constructor.bind(obj,...args);
var res = before();
return typeof res === 'object' ? res || obj : obj; 
// 三目运算符,res为函数执行的结果,如果return的结果为object,则返回res,没有就返回obj
// res || obj? 这么写是因为res可能为null,而 typeof只会判断二进制前三位,
// null 和 object二进制前三位存储为0,所以判断不准
// 因此这么写当res为null时也会返回obj,只有其为object时才会返回res
}

OK,看到这里大家肯定也知道我们可以优化一部分了。我们可以把创建对象到绑定prototype 以及 从绑定this到判断结果这一段优化:

function myNew(constructor,...args){
// 创建空对象,obj的__proto__继承constructor.prototype
const obj = Object.create(constructor.prototype);
// 利用apply绑定this并执行构造函数直接获得结果
const res = constructor.apply(obj, args);
return typeof res === 'object' ? res || obj : obj; 
}

总结

想要手写一个new,就要深深记住它在创建过程中会发生的事情,所以要记住以下五点!!!!!!

  1. 创建新对象:创建一个全新的空对象{}
  2. 链接原型:将这个新对象的[[Prototype]](即__proto__)链接到构造函数的prototype对象
  3. 绑定this:将构造函数中的this绑定到这个新对象
  4. 执行构造函数:执行构造函数中的代码(通常用于初始化对象)
  5. 返回对象:如果构造函数没有返回对象,则自动返回这个新对象

转自https://juejin.cn/post/7533521571568336938


该文章在 2025/8/5 9:22:58 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2025 ClickSun All Rights Reserved