【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. 如果构造器中没有返回对象,则返回上面的创建出来的对象
相关推荐
Mr.Jessy几秒前
Web APIs 学习第四天:DOM事件进阶
开发语言·前端·javascript·学习·ecmascript
云枫晖3 分钟前
前端工程化实战:手把手教你构建项目脚手架
前端·前端工程化
醉方休5 分钟前
开发一个完整的Electron应用程序
前端·javascript·electron
故作春风11 分钟前
手把手实现一个前端 AI 编程助手:从 MCP 思想到 VS Code 插件实战
前端·人工智能
不会算法的小灰18 分钟前
Vue.js 基础教程:从入门到实践
前端·javascript·vue.js
掘金一周22 分钟前
没开玩笑,全框架支持的 dialog 组件,支持响应式| 掘金一周 11.6
前端·人工智能
拉不动的猪35 分钟前
浏览器&Websocket&热更新
前端·javascript·vue.js
Never_Satisfied1 小时前
在JavaScript中,将包含HTML实体字符的字符串转换为普通字符
开发语言·javascript·html
im_AMBER1 小时前
React 12
前端·javascript·笔记·学习·react.js·前端框架
开开心心就好1 小时前
电脑音质提升:杜比全景声安装详细教程
java·开发语言·前端·数据库·电脑·ruby·1024程序员节