第二话:JS中new操作符的原理

摘要

用最简单易懂的话,解释复杂的问题。

想必各位总是在面试中被面试官问到:

知道JS中new操作符的原理吗,可以简单实现一下吗?

如果你是第一次碰到这种问题,一定满脑子都是问号。new不是操作符吗?我怎么手撕啊。

其实,只需要实现一个方法,方法接受一个构造函数为参数,返回一个实例对象即可。

在实现之前,我们先简单用ES5来实现一个People类:

function Peopple() {this.name = "John"
}const people = new Peopple();console.log(people.name);

1.处理对象的属性

现在,我们希望实现一个方法,接受People方法为参数,返回一个People类的实例对象。

那就先把方法创建出来呗:

function _new (constructor) {const obj = {};return obj;
}

我们希望返回的obj能够成为People类的实例,那换句话来说,我们就是希望obj这个对象能够执行一遍People类的构造函数不是吗

那我们能直接调用People(obj)吗?
肯定不能,因为People里面的this不是obj啊,那有什么方法能够改变People里的this指向吗?

这不就来了吗,改变对象this指向的方法一共有三个,call, apply, bind。这里我们就用call来改一下People类的this指向呗,让它指向obj。

function _new (constructor) {const obj = {};constructor.call(obj);return obj;
}const peopple2 = _new(Peopple);console.log(peopple2.name);

现在我们就可以拿到People类的实例化对象了,并且也能访问对应的属性了。
这里读者可以完善一下,如果带有参数的构造函数应该怎么写。

那写到这里就能让面试官满意了吗????

面试官继续问:

你这种写法,挂载在类原型链上的方法是怎么触发的呢?

2.处理对象的方法

我们知道,类的方法我们一般挂载在原型链上,这样可以保证所有的实例化对象共用一个类方法

function Peopple() {this.name = "John"
}Peopple.prototype = {sayName: function () {console.log(this.name);}
}const people = new Peopple();people.sayName();

而我们刚才的实现方式,返回的对象,并不能够拿到类原型链上的东西。所以,我们希望创建对象的时候,能够让这个对象的__proto__指向类的prototype。

这不就来了吗。Object.create(XXX.prototype)不就是干这个的吗。
当然你也可以通过obj.__proto__ = XXX.prototype这种方式来实现。

现在我们就来重新修改一下我们的代码:

function _new (constructor) {const obj = Object.create(constructor.prototype);constructor.call(obj);return obj;
}const peopple2 = _new(Peopple);peopple2.sayName();

写到这里,你擦了擦汗,心想这回应该可以了吧。此时面试官微微一笑:

如果构造函数有返回值时,你实现的这个方法处理的对吗?

3.处理构造函数的返回值

在使用new操作符的时候,有一个需要注意的事情就是,当构造函数的返回值是一个对象的时候,new出来的对象就是返回的对象。

function Peopple() {this.name = "John";return {name: 'Jack'}
}const people = new Peopple();console.log(people.name); // Jack

而我们实现的方法,是直接返回构造好的新对象。所以我们还要处理一下,只需要当传进来的构造函数有返回值时,直接给他返回回去就好了。

function _new (constructor) {const obj = Object.create(constructor.prototype);const result = constructor.call(obj);if (result) return result;return obj;
}const peopple2 = _new(Peopple);console.log(peopple2.name);

Ok,现在我们从,对象的属性、对象的方法、以及构造函数的返回值三个点,手写了一个_new方法。

如果下次有面试官问你:请简单实现一下new的原理。请展示就完了。

最后,希望这篇文章对屏幕前的你有些许的帮助,笔芯♥️。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/885247.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

粤荣学校与亲邻家政达成合作,创造双向人才输送机制

原标题:超过大学生月薪!粤荣学校与亲邻家政达成合作,创造双向人才输送机制,解决中年人就业难题! 广州市白云区粤荣职业培训学校余智强校长与广州亲邻家政服务有限公司朱利生经理于2024年11月8日下午共同签署了一份重要…

【MacOS实操】如何基于SSH连接远程linux服务器

MacOS上远程连接linux服务器,可以使用ssh命令pem秘钥文件连接。 一、准备pem秘钥文件 如果已经有pem文件,则跳过这一步。如果手上有ppk文件,那么需要先转换为pem文件。 macOS 的默认 SSH 客户端不支持 PPK 格式,你需要将 PPK 文…

parseInt 是一个内置的 JavaScript 函数,用于将字符串转换为整数。

parseInt(options.checkNumber, 10) 中的 10 表示将字符串转换为十进制整数。 解释 parseInt 函数: parseInt 是一个内置的 JavaScript 函数,用于将字符串转换为整数。它有两个参数: 第一个参数是要转换的字符串。第二个参数是转换时使用的基…

鸿蒙ArkTS中的布局容器组件(Scroll、List、Tabs)

1、Scroll组件 Scroll组件是一个可滚动的容器组件,用于在子组件的布局尺寸超过父组件尺寸时提供滚动功能。它允许在其内部容纳超过自身显示区域的内容,并通过滚动机制来查看全部内容。这对于显示大量信息(如长列表、长篇文本或大型图像等&…

ElasticSearch备考 -- Manage the index lifecycle (ILM)

一、题目 在集群中,数据首先分布在data_hot节点,rollover 设置max_age:3d, max_docs:5,max_size:50gb, 优先级为100。 max_age:15s, forcemarge 段合并,数据迁移到data_warm节点, 副本数为0,优先级为50 max_age:30s, 数…

信息安全工程师(81)网络安全测评质量管理与标准

一、网络安全测评质量管理 遵循标准和流程 网络安全测评应严格遵循国家相关标准和流程,确保测评工作的规范性和一致性。这些标准和流程通常包括测评方法、测评步骤、测评指标等,为测评工作提供明确的指导和依据。 选择合格的测评团队 测评团队应具备相关…

使用 Python 构建代理池并测试其有效性

前言 在本篇文章中,我们将介绍如何通过 Python 脚本来构建一个代理池,并且对这些代理的有效性进行测试。整个流程涵盖了从网站抓取代理信息、存储这些信息以及异步地测试代理的有效性。这个脚本可以用作网络爬虫或其他需要使用代理服务器的应用的基础工具。 目标网站 一、…

设计者模式之策略模式

前言 在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都写在对象中,将会使对象变得异常复杂;而且有时候支持不频繁使用的算法也是一个性能负担。 如何在运行时根据需要透明地更改对象的算…

tomcat 开启远程debug模式

1.修改位置 CATALINA_OPTS"-Xdebug -Xrunjdwp:transportdt_socket,address*:8000,servery,suspendn"2.修改环境变量的方式 apache-tomcat-9.0.86/bin/setenv.sh export JAVA_HOME/opt/jdk1.8.0_171 export CATALINA_HOME/opt/apache-tomcat-9.0.86 export JAVA_OP…

AI辅助论文写作的利弊

人工智能的时代,AI从自动驾驶到智能家居,慢慢的都成为了我们生活中的一部分。可当AI被放到学术研究领域,特别是撰写论文这一问题上时,却出现了大量的争议,认为AI撰写论文会削弱该有的批判性思维能力。那不用AI撰写论文…

vue3+less使用主题定制(多主题定制)可切换主题

假如要使用两套主题:蓝色、红色 例如: 首先确保自己的vue3项目有less,这边不多做接入解释 1、在src目录下建一个styles文件夹,在syles文件夹下面新建两个less文件:theme.less和variables.less; theme.le…

后端Node学习项目-项目基础搭建

前言 各位好,我是前端SkyRain。最近为了响应公司号召,开始对后端知识的学习,作为纯粹小白,记录下每一步的操作流程。 项目仓库:https://gitee.com/sky-rain-drht/drht-node 因为写了文档,代码里注释不是很…

Maven(六)mvn 命令将 jar 包推送到 远程/本地仓库

目录 一、deploy - 推送到远程仓库1.1 命令语法:1.2 执行结果:1.3 可能遇到的问题问题1:with status code 401问题2:with status code 405问题3:Cannot deploy artifact from the local repository 二、install - 推送…

C语言心型代码解析

方法一 心型极坐标方程 爱心代码你真的理解吗 笛卡尔的心型公式&#xff1a; for (y 1.5; y > -1.5; y - 0.1) for (x -1.5; x < 1.5; x 0.05) 代码里面用了二个for循环&#xff0c;第一个代表y轴&#xff0c;第二个代表x轴 二个增加的单位不同&#xff0c;能使得…

Axure设计之三级联动选择器教程(中继器)

使用Axure设计三级联动选择器&#xff08;如省市区选择器&#xff09;时&#xff0c;可以利用中继器的数据存储和动态交互功能来实现。下面介绍中继器三级联动选择器设计的教程&#xff1a; 一、效果展示&#xff1a; 1、在三级联动选择器中&#xff0c;首先选择省份&#xff…

使用Docker-Compose安装redis,rabbitmq,nacos,mysql,nginx,tomcat,portainer组件教程

因为开发经常会用到一些组件&#xff0c;又不想在本地启动&#xff0c;所以买了个服务器&#xff0c;然后将这些组件都安装到服务器上以便开发使用。下面就记录下使用docker-compose安装组件的教程以及一些需要注意的地方。 关于docker和docker-compose的安装在另一篇博客中有…

安装PyG

PyG安装 官方链接 Installation — pytorch_geometric documentation (pytorch-geometric.readthedocs.io) 安装步骤&#xff1a; 步骤一&#xff1a;安装Anaconda和CUDA 安装Anaconda-CSDN博客安装CUDA-CSDN博客 步骤二&#xff1a;查看支持的Python版本 步骤三&#xf…

如何在Linux中使用Cron定时执行SQL任务

文章目录 前言一、方案分析二、使用步骤1.准备脚本2.crontab脚本执行 踩坑 前言 演示数据需要每天更新监控数据&#xff0c;不想手动执行&#xff0c;想到以下解决方案 navicat 创建定时任务java服务定时执行linux crontab 定时执行sql脚本 一、方案分析 我选择了第三个方案…

夜天之书 #103 开源嘉年华纪实

上周在北京参与了开源社主办的 2024 中国开源年会。其实相比于有点明显班味的“年会”&#xff0c;我的参会体验更像是经历了一场中国开源的年度嘉年华。这也是在会场和其他参会朋友交流时共同的体验&#xff1a;在开源社的 COSCon 活动上&#xff0c;能够最大限度地一次性见到…

Android Handler

Handler用于多线程消息分发和处理。与handler相关的几个对象&#xff1a;Message, Looper&#xff0c;MessageQueue, ThreadLocal. Handler是Message的消费者。 MessageQueue是容器。 Looper是整个Message分发的驱动。 Handler中有多种发送消息的方法&#xff0c;其中postxx…