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

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

相关推荐
兩尛15 分钟前
c++面试常问2
开发语言·c++·面试
爱上好庆祝24 分钟前
学习js的第2天
前端·css·学习·html·css3
l1t24 分钟前
DeepSeek v4辅助生成的单文件SQL查询示例页面
javascript·数据库·sql
Csvn1 小时前
SEO 优化
前端
笋笋~1 小时前
el-tree 拖拽事件隔离:实现句柄独立控制,区域分离
javascript·vue.js·elementui
天外飞雨道沧桑1 小时前
详解CSS中的Containing Block:概念、规则与实战解析
前端·css
彩票管理中心秘书长1 小时前
Git 图形化交互工具大全:从官方 GUI 到高级扩展
前端
ID_180079054731 小时前
Python 实现京东商品详情 API 数据准确性校验(极简可直接用)
java·前端·python
前端那点事1 小时前
Vue生命周期速查:Vue2+Vue3钩子全解析,新手也能秒懂
前端·vue.js
陆枫Larry1 小时前
横向滚动列表紧贴屏幕边缘问题:原理分析与解决方案
前端