【JavaScript】手撕前端面试题:手写new操作符❗❗❗

前言

当我们在使用构造函数的时候,要实例化一个对象,直接使用new就好了,这样新对象就继承到了构造函数的所有属性和方法。那你有思考过new是啥嘛?它的工作流程是什么样的?这也是在前端面试中经常考的一道手写题,今天就让我们一起拿下它!

new是什么?

在手写new之前,让我们先来好好认识一下new是什么!

new 操作符在 JavaScript 中用于创建一个用户定义的对象类型的实例或已有内置对象类型的实例。

new的执行步骤

1.创建新对象

首先,new 操作符会创建一个新的空对象 {}。这个对象将作为新实例的基础。

  1. 设置原型链

接下来,新创建的对象会被链接到构造函数的 prototype 属性所指向的对象。这意味着新对象将继承构造函数原型上的所有属性和方法。

ini 复制代码
function Person(name) {
this.name = name;
} 
const person1 = new Person('Alice'); 
console.log(person1.__proto__ === Person.prototype); // true

如果你对原型对象与原型链还不是很了解可以先看看我的上一篇文章js原型与原型链(精心总结)(一文搞懂)(建议收藏)❗❗❗

  1. 执行构造函数

然后,构造函数被调用,并且 this 被绑定到新创建的对象上。构造函数可以为新对象添加属性和方法。

javascript 复制代码
function Person(name) {
this.name = name;
this.sayHello = function() { 
console.log(`Hello, my name is ${this.name}`);
     }; 
} 
const person1 = new Person('Alice');
person1.sayHello(); // 输出: Hello, my name is Alice
  1. 返回新对象

最后,如果构造函数没有显式返回对象,则 new 操作符会自动返回新创建的对象。如果有返回值并且是对象类型(包括函数),则返回该对象;如果是非对象类型(如字符串、数字等),则忽略并返回新创建的对象。

javascript 复制代码
function Person(name) {
    this.name = name;

    // 如果返回的是对象,则返回该对象
    return { name: 'Override' };
}

const person1 = new Person('Alice');
console.log(person1.name); // 输出: Override

function AnotherPerson(name) {
    this.name = name;

    // 如果返回的是非对象类型,则忽略并返回新创建的对象
    return 'Not an object';
}

const anotherPerson = new AnotherPerson('Bob');
console.log(anotherPerson.name); // 输出: Bob

手写new

了解完new的执行步骤,那让我们开始直接手写一个new来更好的理解new吧! 第一步 先随便写一个构造函数

js 复制代码
function Person(name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype.sayName = function () {
    console.log(this.name)
}

在构造函数中我们写了name和age属性,并在Person的原型对象上写了sayName方法。

第二步

要写一个手写new,我的思路就是根据new的四个执行步骤来就行,那么我们第二部就是要创建一个新的空对象

js 复制代码
function Person(name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype.sayName = function () {
    console.log(this.name)
}
function objectFactory() {
    const obj = {};
}

第三步

设置原型链

js 复制代码
function Person(name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype.sayName = function () {
    console.log(this.name)
}
function objectFactory() {
    const obj = {};//空对象的创建
    const Constructor = [].shift.call(arguments);
    obj.__proto__ = Constructor.prototype;
    Constructor.apply(obj, arguments);
    
}
let awei = objectFactory(Person, 'awei', 23)
console.log(awei);

这里我们用 const Constructor = [].shift.call(arguments); Constructor来提取第一个参数,let awei = objectFactory(Person, 'awei', 23) 可以看到传入的第一个参数是构造函数Person 这时候我们只需要将空对象的原型指向构造函数的原型对象就完成了原型链的设置了obj.__proto__ = Constructor.prototype;

第四步 设置返回值

js 复制代码
function Person(name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype.sayName = function () {
    console.log(this.name)
}
function objectFactory() {
    const obj = {};
    const Constructor = [].shift.call(arguments);
    obj.__proto__ = Constructor.prototype;
    Constructor.apply(obj, arguments);
    return obj; 
}
let awei = objectFactory(Person, 'awei', 23)
console.log(awei)

这样我们就实现了new的四个执行步骤,让我们来看看结果吧

总结

new 做了什么?

  1. 在构造器内部创建一个新的对象
  2. 这个对象内部的隐式原型指向该构造函数的显式原型
  3. 让构造器中的 this 指向这个对象
  4. 执行构造器中的代码
  5. 如果构造器中没有返回对象,则返回上面的创建出来的对象
相关推荐
Jerry4 分钟前
Jetpack Compose 中的状态
前端
dae bal1 小时前
关于RSA和AES加密
前端·vue.js
柳杉1 小时前
使用three.js搭建3d隧道监测-2
前端·javascript·数据可视化
倔强青铜三1 小时前
苦练Python第39天:海象操作符 := 的入门、实战与避坑指南
人工智能·python·面试
lynn8570_blog1 小时前
低端设备加载webp ANR
前端·算法
LKAI.2 小时前
传统方式部署(RuoYi-Cloud)微服务
java·linux·前端·后端·微服务·node.js·ruoyi
刺客-Andy2 小时前
React 第七十节 Router中matchRoutes的使用详解及注意事项
前端·javascript·react.js
前端工作日常2 小时前
我对eslint的进一步学习
前端·eslint
禁止摆烂_才浅3 小时前
VsCode 概览尺、装订线、代码块高亮设置
前端·visual studio code
程序员猫哥3 小时前
vue跳转页面的几种方法(推荐)
前端