new 操作符的原理及手写

什么是 new ?

在JavaScript中,new 是一个用于创建对象实例的关键字。它用于调用构造函数,并返回一个新的对象。

使用

  • 使用 new 创建的对象,可以访问构造函数及其原型链上的属性和方法。
js 复制代码
function User(name) {
  this.name = name;
  this.isAdmin = false;
}

let user = new User("Jack");

console.log(user.name); // Jack
user.isAdmin(); // yes
  • 通常,构造器没有 return 语句。它们的任务是将所有必要的东西写入 this,并自动转换为结果。

  • 但是,如果这有一个 return 语句,那么规则就简单了:

    • 如果 return 返回的是一个对象,则返回这个对象,而不是 this。
    • 如果 return 返回的是一个原始类型,则忽略。
js 复制代码
function BigUser(name) {

  this.name = name;

  return { name: "Godzilla" };  // <-- 返回这个对象
}

const user = new BigUser("John");
console.log(user.name);  // Godzilla,得到了那个对象
  • 这里有一个 return 为空的例子(或者我们可以在它之后放置一个原始类型,没有什么影响):
js 复制代码
function SmallUser(name) {

  this.name = name;

  return; // <-- 返回 this
}

const user = new SmallUser("John");
console.log(user.name)  // John

实现原理

  1. 创建一个新对象
  2. 新对象的原型指向构造函数的原型对象
  3. 构造函数中的this指向该对象(也就是为这个对象添加属性和方法)
  4. 构造函数返回的是对象则返回它,如果不是则返回一开始创建的新对象

手写 new 操作符

js 复制代码
function myNew(constructor,...args){
    // 创建一个新对象,原型指向构造函数的原型对象
    const obj = Object.create(constructor.prototype);
    // 将构造函数的this指向新对象。如果构造函数没有返回对象时,result为undefined,this指向obj;如果构造函数返回了一个对象,this指向返回的对象
    const result = constructor.apply(obj,args);
    // 如果构造函数返回了一个对象,则返回该对象;否则,返回新对象
    return result instanceof Object ? result : obj; 
}
  • 测试:
js 复制代码
function myNew(constructor,...args){
    // 创建一个新对象,原型指向构造函数的原型对象
    const obj = Object.create(constructor.prototype);
    // 将构造函数的this指向新对象。如果构造函数没有返回对象时,result为undefined,this指向obj;如果构造函数返回了一个对象,this指向返回的对象
    const result = constructor.apply(obj,args);
    // 如果构造函数返回了一个对象,则返回该对象;否则,返回新对象
    return result instanceof Object ? result : obj; 
}


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

User.prototype.say = function () {
    console.log(this.name)
}

const p = myNew(User, "qqq", 20)
console.log(p) // User {name: 'qqq', age: 20}
p.say() // qqq

如有问题欢迎在评论区讨论,一起进步!

相关推荐
IT_陈寒2 分钟前
一文搞懂React的核心概念
前端·人工智能·后端
考研保研资料分享12 分钟前
2022投资学跨保中国农业大学公共管理:四校面试与海投复盘
面试·职场和发展
薛一半20 分钟前
Redux实战:组件状态管理全解析
开发语言·前端·javascript·react.js
风骏时光牛马31 分钟前
功能模块性能测试用例验证
前端
对空六课2 小时前
两个统计平台数据不同:用同一时间窗和事件样本做差异定位
大数据·前端·网络·数据库
十年Java程序媛9 小时前
Java枚举Enum完整教程|替代静态常量,开发与面试要点
java·开发语言·spring boot·后端·面试
lpfasd12310 小时前
node-sass 停止维护!老项目迁移 Dart Sass 完整教程
前端·rust·sass
考研保研资料分享11 小时前
2022年马理论保研复盘:南师大原著题、首师大追问与上财选择
面试
考研保研资料分享11 小时前
2022编辑出版跨保西北大学中国史:五校面试与九月补材料
面试·职场和发展
Data analyse45612 小时前
rnweb 回放数据量太大怎么办?分片存储与断点续传的实现思路
前端·网络·算法·数据分析