JavaScript 手动实现new操作符

本文详细解析构造函数与原型对象的关系,包括实例化过程与new操作符的工作原理,并演示如何手动实现new。探讨了构造函数的prototype属性、实例的__proto__属性和原型对象的constructor属性。同时,展示了如何在构造函数中返回对象,以及自定义myNew函数来模拟new操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 回顾构造函数、实例、原型对象的关系

  1. 构造函数prototype属性指向了构造函数的原型对象
  2. 实例对象是由构造函数创建的,实例对象的__proto__属性指向了构造函数的原型对象
  3. 构造函数的原型对象的constructor属性指向了构造函数实例对象原型constructor属性(usr1. __proto__.constructor)也指向了构造函数

现有构造函数StarStar的实例对象usr1,其三者关系如图所示:

2. new操作符做了什么

简单来说,当我们使用new操作符为构造函数创建实例时,发生了下面4件事:

  1. 创建一个新对象
  2. 新对象添加属性__proto__,将该属性链接至构造函数原型对象
  3. 执行构造函数,this被绑定在新对象
  4. 确保返回一个对象

如下所示,通过new操作符,为构造函数实例化了一个对象:

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

const usr1 = new Person('Jack', 18);
console.log(usr1);
// Person { name: 'Jack', age: 18 }

若在构造函数中,返回一个对象,那么通过new操作符得到的对象,就是构造函数中返回的对象:

function Person(name, age) {
    this.name = name;
    this.age = age;
    // 构造函数中返回一个对象
    return {
        a: 1,
    };
}

const usr1 = new Person('Jack', 18);
console.log(usr1);
// { a: 1 }

3. 手动实现new

知道了new操作符背后做的事情,我们可以自己写一个myNew,实现相同的功能。

// 定义构造函数
function Person(name, age) {
    this.name = name;
    this.age = age;
}

// 手动实现new:
// constructor: 构造函数
// ...args: 构造函数参数
function myNew(constructor, ...args) {
    // 1. 创建一个新对象
    const obj = {};
    // 2. 为新对象添加属性__proto__,将该属性链接至构造函数的原型对象
    obj.__proto__ = constructor.prototype;
    // 3. 执行构造函数,this被绑定在新对象上
    const res = constructor.call(obj, ...args);
    // 4. 确保返回一个对象
    return res instanceof Object ? res : obj;
}

const usr1 = myNew(Person, 'Jack', 18);
const usr2 = new Person('Jack', 18);

console.log(usr1);
console.log(usr2);

在浏览器运行环境下,查看输出结果:

若构造函数本身返回一个对象,自己实现的myNew也可以返回这个对象:

function Person(name, age) {
    this.name = name;
    this.age = age;
    // 构造函数中返回一个对象
    return {
        a: 1,
    };
}

function myNew(constructor, ...args) {
    // 1. 创建一个新对象
    const obj = {};
    // 2. 为新对象添加属性__proto__,将该属性链接至构造函数的原型对象
    obj.__proto__ = constructor.prototype;
    // 3. 执行构造函数,this被绑定在新对象上
    const res = constructor.call(obj, ...args);
    // 4. 确保返回一个对象
    return res instanceof Object ? res : obj;
}

const usr2 = myNew(Person, 'Jack', 18);
console.log(usr2);
// { a: 1 }

JavaScript常见手写代码:

「GitHub—code-js」

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

火星飞鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值