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;

参考文献

相关推荐
一斤代码1 小时前
vue3 下载图片(标签内容可转图)
前端·javascript·vue
中微子1 小时前
React Router 源码深度剖析解决面试中的深层次问题
前端·react.js
光影少年2 小时前
从前端转go开发的学习路线
前端·学习·golang
中微子2 小时前
React Router 面试指南:从基础到实战
前端·react.js·前端框架
3Katrina2 小时前
深入理解 useLayoutEffect:解决 UI "闪烁"问题的利器
前端·javascript·面试
前端_学习之路3 小时前
React--Fiber 架构
前端·react.js·架构
coderlin_3 小时前
BI布局拖拽 (1) 深入react-gird-layout源码
android·javascript·react.js
伍哥的传说3 小时前
React 实现五子棋人机对战小游戏
前端·javascript·react.js·前端框架·node.js·ecmascript·js
qq_424409193 小时前
uniapp的app项目,某个页面长时间无操作,返回首页
前端·vue.js·uni-app
我在北京coding3 小时前
element el-table渲染二维对象数组
前端·javascript·vue.js