JavaScript | 使用new关键字的时候做了什么?

new的原理

现在要创建一个新的对象,比如这个对象是一个人(Person),代码如下:

javascript 复制代码
function Person(name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function () {
        console.log(this.name);
    };
}
let person1 = new Person("Walter White", 50, "Chemist");

当使用new操作符的时候,进行以下操作:

  1. 在内存中创建一个新的对象
  2. 将这个对象的__proto__指向构造函数的prototype(原型对象)
  3. this指向这个新的对象
  4. 执行构造函数内部的代码,给这个对象添加属性与方法
  5. 返回这个新的对象(所以构造函数里面不需要写reutrn

下面来看下代码上的实现:

javascript 复制代码
function Person(name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function () {
        console.log(this.name);
    };
}

function myNew(Class, ...args) {
    // 1. 在内存中创建一个新的对象
    const o = new Object();
    // 2. 将这个对象的__proto__指向构造函数的prototype(原型对象)
    o.__proto__ = Class.prototype;
    // 3.让this指向这个对象
    // 4.指向构造函数的代码,给这个对象添加属性与方法
    const result = Class.call(o, ...args);
    // 5.返回这个新对象
    return typeof result === "object" ? result : o;
}

// 使用new创建
let person1 = new Person("Walter White", 50, "Chemist");
// 使用手写函数创建
let person2 = myNew(Person, "Walter White", 50, "Chemist");
console.log(person1); // Person {name: 'Walter White', age: 50, job: 'Chemist', sayName: ƒ}
console.log(person2); // Person {name: 'Walter White', age: 50, job: 'Chemist', sayName: ƒ}

补充

myNew函数优化写法:

javascript 复制代码
function myNew(Class, ...args) {
    // 1. 在内存中创建一个新的对象
    // 2. 将这个对象的__proto__指向构造函数的prototype(原型对象)
    const obj = Object.create(Class.prototype);
    // 3.让this指向这个对象
    // 4.指向构造函数的代码,给这个对象添加属性与方法
    let result = Class.apply(obj, [...args]);
    // 5.返回这个新对象
    return typeof result === "object" ? result : obj;
}

const obj = Object.create(Class.prototype);等价于

javascript 复制代码
// 1. 在内存中创建一个新的对象
const o = new Object();
// 2. 将这个对象的__proto__指向构造函数的prototype(原型对象)
o.__proto__ = Class.prototype;

参考文献

相关推荐
负责的蛋挞42 分钟前
异步HttpModule的实现方式
java·服务器·前端
丹宇码农3 小时前
把 HLS 字幕玩出花:zwPlayer 如何让 M3U8 视频支持全文搜索、翻译与码率自适应
前端·javascript·音视频·hls·视频播放器
2501_943782353 小时前
【共创季稿事节】猜数字游戏:二分法思维与交互式反馈
前端·游戏·microsoft·harmonyos·鸿蒙·鸿蒙系统
GV191rLvq4 小时前
基于Socket实现的最简单的Web服务器【ASP.NET原理分析】
服务器·前端·asp.net
吠品4 小时前
LangChain 里 tool_call_id 为空?一次 MCP 工具集成的排查记录
前端
微信开发api-视频号协议4 小时前
企业微信二次开发中的文件系统设计:媒体资源、临时文件与业务附件
前端·微信·企业微信·媒体·ipad·微信开放平台
柒和远方4 小时前
Phase 7.4 学习博客:为什么多 API 项目需要 Swagger / OpenAPI
前端·后端·架构
张龙6874 小时前
拼多多开放平台对接踩坑实录:从 CLIENT_ID 配置到 MD5 签名算法的完整填坑指南
前端
GuWenyue4 小时前
提示词彻底过时?一套上下文工程方案,3步让LLM落地生产,代码直接复用
前端·javascript·人工智能