面试官:说说 new 的执行过程

本文为面试专题之JavaScript进阶------原理篇系列,new 的执行过程。

面经梳理见:2024年,龙年大吉吧。裁员,内卷,逆流而上,万字面经梳理

介绍

引用MDN的官方介绍,是这样定义 new 的:

new 运算符允许开发人员创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例

注:new 在JavaScript中是一个关键字。

语法

js 复制代码
new constructor
new constructor()
new constructor(arg1)
new constructor(arg1, arg2)
new constructor(arg1, arg2, /* ..., */ argN)
  • constructor:一个指定对象实例的类型的类或函数。
  • arg:一个用于被 constructor 调用的值列表。new Foonew Foo() 等价,换句话说:如果没有指定参数列表,则在不带参数的情况下调用 Foo。

用法与特点

举个栗子:

js 复制代码
function Parent(name) {
  this.name = name;
}
Parent.prototype.sayName = function () {
  return `我的名字是:${this.name}`
}

const son = new Parent("小帅");
console.log(son.name); // 访问构造函数里的属性
// 小帅

console.log(son.sayName()); // 访问原型里的属性
// 我的名字是:小帅
  1. 可以访问构造函数里的属性
  2. 可以访问原型上的属性

描述

当使用 new 关键字调用函数时,该函数将被用作构造函数。new 将执行以下操作:

  1. 创建一个空的 JavaScript 对象 obj
  2. objprototype 指向构造函数的 prototype 属性
  3. 使用给定参数执行构造函数,并将 obj 绑定为 this 的上下文(换句话说,在构造函数中的所有 this 引用都指向 obj
  4. 判断函数的返回值类型,如果是值类型,返回创建的对象。如果是引用类型,就返回这个引用类型的对象

实现

js 复制代码
function myNew() {
  // 1. 获取构造函数(参数对象里的第一个)
  const constructor = [...arguments][0]
  // 2. 创建对象
  const obj = Object.create(constructor.prototype)
  // 3. 执行传入构造函数,并修改 this
  const result = constructor.apply(obj, [...arguments].slice(1))
  // 4. 根据执行函数的返回值,判断是返回结果还是返回 obj 对象
  const isResult = (typeof result === 'object' && result !== null) || typeof result === "function"
  return isResult ? result : obj
}

或者你也可以这样写:

js 复制代码
function myNew(fn, ...args) {
  // 1. 获取构造函数
  const constructor = fn
  // 2. 创建对象 ,并指定原型
  const obj = Object.create(constructor.prototype)
  // 3. 执行传入构造函数,并修改 this
  const result = constructor.apply(obj, args)
  // 4. 根据执行函数的返回值,判断是返回结果还是返回 obj 对象
  const isResult = (typeof result === 'object' && result !== null) || typeof result === "function"
  return isResult ? result : obj
}

// 测试下,结果也是一致的
const son = myNew(Parent, "小帅");
console.log(son.name); // 访问构造函数里的属性
// 小帅

console.log(son.sayName()); // 访问原型里的属性
// 我的名字是:小帅

其中步骤 2 也可以这样写:

js 复制代码
// 1. __proto__
const obj = new Object()
obj.__proto__ = constructor.prototype

// 2. setPrototypeOf
// 指定原型链的终点null为其原型
const obj = Object.create(null) 
const propto = constructor.prototype
// setPrototypeOf方法可以把Object.create(null)指定null的创建强制修改原型
Object.setPrototypeOf(obj, propto) 

总结

简单来说,new 做的事情就是继承属性和方法,并改变this的上下文。

其实,通过手写 new 的实现,你应该可以发现,针对本文 new 的创建过程这个问题,仔细思考下...

我们完全可以把他看做是对原型链的一种考察,其中涉及的构造函数prototype__proto__Object.createObject.setPrototypeOf 等概念与方法,是不是又特别的熟悉呢?

其实,只要弄懂了JavaScript的原型与继承,也就明白了本文的内容了~

👀原型链的相关进阶文章请持续关注面试专栏的更新~

交流

好了,本文到此结束,欢迎来撩,一起学习🙋‍♂️~

面试相关的文章及代码demo,后续打算在这个仓库(JS-banana/interview: 面试不完全指北 (github.com))进行维护,欢迎✨star,提建议,一起进步~

相关推荐
Asize23 分钟前
HTML5 Canvas 基础:从按帧动画到 ECharts 数据可视化
前端·javascript·canvas
默_笙26 分钟前
🎄 后端给我一堆扁平数据,我 10 行代码把它变成了树
前端·javascript
前端Hardy31 分钟前
又一个 AI 神器火了!
前端·javascript·后端
PBitW1 小时前
GPT训练我的第二天,我表示不过如此!!!😕😕😕
前端·javascript·面试
kyriewen2 小时前
白宫直接给 OpenAI 下了限制令,GPT-5.6 不能随便放出来了
前端·javascript·面试
未秃头的程序猿6 小时前
Java 26正式发布!这3个新特性,让代码量直接减半
java·后端·面试
默_笙7 小时前
🍞 我用 CSS 画了一个会转的 3D 立方体,同事以为我学了 Three.js(这节课真的很神奇,我很喜欢)
javascript
sarasuki7 小时前
JavaScript的对象、new的机制与原型包装类
javascript·后端
weedsfly7 小时前
JavaScript 事件流:彻底搞懂捕获、冒泡与事件委托
前端·javascript·react.js
AI人工智能_电脑小能手7 小时前
【大白话说Java面试题 第125题】【并发篇】第25题:说说 Java 线程的中断机制
java·后端·面试