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;

参考文献

相关推荐
DanB241 分钟前
html复习
javascript·microsoft·html
汉得数字平台6 分钟前
【鲲苍提效】全面洞察用户体验,助力打造高性能前端应用
前端·前端监控
花海如潮淹13 分钟前
前端性能追踪工具:用户体验的毫秒战争
前端·笔记·ux
_丿丨丨_5 小时前
XSS(跨站脚本攻击)
前端·网络·xss
天天进步20155 小时前
前端安全指南:防御XSS与CSRF攻击
前端·安全·xss
呼啦啦呼啦啦啦啦啦啦6 小时前
利用pdfjs实现的pdf预览简单demo(包含翻页功能)
android·javascript·pdf
拾光拾趣录8 小时前
括号生成算法
前端·算法
拾光拾趣录8 小时前
requestIdleCallback:让你的网页如丝般顺滑
前端·性能优化
前端 贾公子8 小时前
vue-cli 模式下安装 uni-ui
前端·javascript·windows
拾光拾趣录9 小时前
链表合并:双指针与递归
前端·javascript·算法