面试常考 | 深入理解 JavaScript 中手写 new 操作符

在 JavaScript 里,new 操作符是创建对象实例的常用方式。不过,你是否好奇它内部是如何工作的呢?这篇文章会详细剖析 new 操作符的原理,还会手把手教你手写一个 new 函数。

什么是 new 操作符

在 JavaScript 中,new 操作符的用途是创建一个用户自定义对象类型的实例,或者创建一个内置对象类型的实例。咱们先看一个简单的例子:

ini 复制代码
function Person(name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype.sayName = function() {
    console.log(`My name is ${this.name}`);
};
const john = new Person('John', 30);
john.sayName(); 

在这个例子中,new Person('John', 30) 创建了一个 Person 构造函数的实例 john。new 操作符完成了以下几个关键步骤:

  1. 创建新对象:一个全新的对象被创建出来。
  1. 设置原型:新对象的原型会被设置为构造函数的 prototype 属性。
  1. 执行构造函数:构造函数会在新对象的上下文中执行,也就是说,构造函数里的 this 会指向新对象。
  1. 返回新对象:如果构造函数没有显式返回一个对象,那么就返回新创建的对象。

手写 new 函数

接下来,我们要自己实现一个 new 函数,以此来深入理解 new 操作符的工作原理。以下是实现代码:

javascript 复制代码
function objectFactory() {
    console.log(arguments,arguments.length);
    const obj = new Object();
    //arguments 类数组对象,没有shift方法 
    // 1.将类数组对象转化为数组对象
    // 2.数组对象调用shift方法
    // 3.将shift方法返回的结果赋值给Constructor
    // 4.删除数组对象的第一个元素
    const Constructor = [].shift.call(arguments);
    console.log(Constructor);
    obj.__proto__ = Constructor.prototype;
    Constructor.apply(obj, arguments);
    console.log(obj);
    return obj;
}

代码解释

  1. 创建新对象
ini 复制代码
const obj = new Object();

这行代码创建了一个全新的空对象。

  1. 获取构造函数
ini 复制代码
const Constructor = [].shift.call(arguments);

arguments 是一个类数组对象,它包含了传递给 objectFactory 函数的所有参数。我们借助 [].shift.call(arguments) 把 arguments 的第一个元素取出来,这个元素就是构造函数。

  1. 设置原型
ini 复制代码
obj.__proto__ = Constructor.prototype;

这行代码把新对象 obj 的原型设置为构造函数的 prototype 属性,这样新对象就可以继承构造函数原型上的属性和方法了。

  1. 执行构造函数
arduino 复制代码
Constructor.apply(obj, arguments);

使用 apply 方法在新对象 obj 的上下文中执行构造函数,这样构造函数里的 this 就会指向新对象。

  1. 返回新对象
kotlin 复制代码
return obj;

最后,返回新创建的对象。

使用自定义的 new 函数

ini 复制代码
let shuai = objectFactory(Person, "小帅", 20);
console.log(shuai.name);
shuai.sayName();

在这个例子中,我们用 objectFactory 函数创建了一个 Person 构造函数的实例 shuai。可以看到,shuai 对象拥有 name 属性,并且能调用 sayName 方法。

总结

通过手写 new 函数,我们对 new 操作符的工作原理有了更深入的理解。new 操作符本质上就是创建一个新对象,设置其原型,执行构造函数,最后返回新对象。掌握这个原理,有助于你更好地理解 JavaScript 中的面向对象编程。

希望这篇文章能帮助你理解 JavaScript 中 new 操作符的原理和实现方式。如果你有任何疑问或者建议,欢迎在评论区留言。

相关推荐
AndyLaw13 分钟前
统计字符数错一半,我被 length 坑了两次
前端·javascript
关羽的小刀15 分钟前
Element-UI最新版暗藏Lodash漏洞?一次真实项目安全排查记录
前端
张志鹏PHP全栈15 分钟前
Vue3第五天,ref 和 reactive的介绍和区别
前端·vue.js
郭邯16 分钟前
import.meta对象是什么?
前端
绝无仅有26 分钟前
Redis 服务挂掉排查与解决
后端·面试·github
用泥种荷花33 分钟前
【NPM 笔记(一)】NPM 入门知识:命令、依赖与脚本核心
前端
大巨头33 分钟前
在vscode中使用通义灵码插件记录分享
前端
江城开朗的豌豆36 分钟前
Vue/React凭什么吊打传统前端?6年老司机带你揭秘它们的性能杀招!
前端·javascript·vue.js
江城开朗的豌豆36 分钟前
虚拟DOM:为什么React/Vue比直接操作DOM快10倍?
前端·javascript·vue.js
mrsk37 分钟前
JavaScript中的大数相加是怎么突破数字的极限的?
前端·javascript·面试