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;

参考文献

相关推荐
pe7er3 小时前
window管理开发环境篇 - 持续更新
前端·后端
We་ct4 小时前
LeetCode 5. 最长回文子串:DP + 中心扩展
前端·javascript·算法·leetcode·typescript
陈随易8 小时前
有生之年系列,Nodejs进程管理pm2 v7.0发布
前端·后端·程序员
冰暮流星8 小时前
javascript之事件代理/事件委托
前端
陈随易10 小时前
AI时代,你还在坚持手搓文章吗
前端·后端·程序员
里欧跑得慢12 小时前
17. Flutter Hero动画实现:让界面过渡更加优雅
前端·css·flutter·web
IT_陈寒12 小时前
Vue的这个响应式陷阱,我debug了一整天才爬出来
前端·人工智能·后端
cn_mengbei12 小时前
用React Native开发OpenHarmony应用:Reanimated共享元素过渡
javascript·react native·react.js
kyriewen12 小时前
前端测试:别为了100%覆盖率而写测试,那是自欺欺人
前端·javascript·单元测试
去伪存真13 小时前
我自己写的第一个skills--project-core-standards
前端·agent