在JavaScript中,new关键字的应用可以说是再平常不过了,最基础的有new Array()、new Set(),再而就是new一个自己创建的构造函数,也就是创建一个该构造函数的示例。如:var person1 = new Person("一颗苹果", 18);但你是否真的了解new以及它的底层原理呢,本文将举出几个例子并且手写一个 new 来带大家深入理解。

new

new的使用方法

function Car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
} const car1 = new Car('Eagle', 'Talon TSi', 1993); console.log(car1.make); //输出: "Eagle"

那么new的过程发生了什么呢

  • 创建一个空对象:创建一个空的简单 JavaScript 对象。为方便起见,我们称之为 newInstance

  • 指定原型链:将 newInstance 的 [[Prototype]] 指向构造函数的 prototype 属性,否则 newInstance 将保持为一个普通对象,其 [[Prototype]] 为 Object.prototype

  • 更改this指向:使用给定参数执行构造函数,并将 newInstance 绑定为 this 的上下文。

  • 返回值:返回newInstance。

手写一个new

function myNew(Fun, ...args) {
let obj = {}
obj.__proto__ = Fun.prototype
Fun.apply(obj, args)
return obj
}
function Person(name,age) {
this.name = name
this.age = age
}
let apple = myNew(Person, '一颗苹果','18')
console.log(apple.name); //输出:一颗苹果
console.log(apple.age); //输出:18
  • ...args:将剩下的元素都放进args

  • obj. __ proto __ = Fun.prototype:将 obj 的原型链指向构造函数的 prototype 属性

  • Fun.apply(obj, args):将构造函数内部的this绑定到obj上,并执行构造函数

通过这一系列操作,我们就可以拿到构造函数中的 nameage属性了

看似完成了,但其实落了很重要的一点

回想一下,我们通过new函数创建一个对象时,除了引用它的属性,我们还会做些什么呢?

let arr = new Array()
arr.push(4)
arr.unshift(3)
console.log(arr);

当然是使用它自带的方法,但是上面并没有给出方法上的引用。这就得引入原型链这个知识点了,我们只需要给Person的原型链上增加我们想要的方法就可以了,实现代码如下:

function myNew(Fun, ...args) {
let obj = {}
obj.__proto__ = Fun.prototype
Fun.apply(obj, args)
return obj
}
function Person(name,age) {
this.name = name
this.age = age
}
Person.prototype.who = function () {
console.log('我是Person的实例对象');
}
Person.prototype.myname = function () {
console.log(this.name)
}
let p = myNew(Person, '一颗苹果')
p.who(); // 输出:我是Person的实例对象
p.myname(); // 输出:一颗苹果
console.log(p.name); // 输出:一颗苹果
这就是我们的最终答案了,把它交给面试官,perfect!!

手写js new,new的过程到底发生了什么的更多相关文章

  1. vue10行代码实现上拉翻页加载更多数据,纯手写js实现下拉刷新上拉翻页不引用任何第三方插件

    vue10行代码实现上拉翻页加载更多数据,纯手写js实现下拉刷新上拉翻页不引用任何第三方插件/库 一提到移动端的下拉刷新上拉翻页,你可能就会想到iScroll插件,没错iScroll是一个高性能,资源 ...

  2. 手写js面向对象选项卡插件

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8&qu ...

  3. 手写JS无缝滚动插件

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8&qu ...

  4. cocos2dx手写js绑定C++

    这两天连续查阅了js绑定c++的非常多文章  , 有手动与自己主动两种方式 . 本来想用自己主动绑定的 , 可是NDK一直下载不下来.....就给算了 . 以下总结一下手动绑定的实现过程 : 一共三步 ...

  5. 手写js代码(一)javascript数组循环遍历之forEach

    注:原文地址http://blog.csdn.net/oscar999/article/details/8671546 我这里是仿照学习! 1.js的数组循环遍历 ①数组的遍历首先想到的是for()循 ...

  6. 前端小插件之手写js循环滚动特效

    很多前端都离不开滚动的特效,调用插件繁琐,后期更改麻烦,考虑到这些因素,自己写了一套无限循环滚动的小特效. 首先滚动特效很好写,用css就可以完成,下面写一个基础css向上循环滚动特效 html &l ...

  7. 手写JS深拷贝

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. js new一个对象的过程,实现一个简单的new方法

    对于大部分前端开发者而言,new一个构造函数或类得到对应实例,是非常普遍的操作了.下面的例子中分别通过构造函数与class类实现了一个简单的创建实例的过程. // ES5构造函数 let Parent ...

  9. UI到底应该用xib/storyboard完成,还是用手写代码来完成?

    UI到底应该用xib/storyboard完成,还是用手写代码来完成? 文章来源:http://blog.csdn.net/libaineu2004/article/details/45488665 ...

  10. 2019前端面试系列——JS高频手写代码题

    实现 new 方法 /* * 1.创建一个空对象 * 2.链接到原型 * 3.绑定this值 * 4.返回新对象 */ // 第一种实现 function createNew() { let obj ...

随机推荐

  1. 强化学习性能测试方法:取最后10个epoch的testing epoch的均值 —— 强化学习中的一种性能测试方法

    参考: https://www.cnblogs.com/devilmaycry812839668/p/17813337.html The Actor-Mimic and expert DQN trai ...

  2. 【安装部署】Apache SeaTunnel 和 Web快速安装详解

    版本说明 由于作者目前接触当前最新版本为2.3.4 但是官方提供的web版本未1.0.0,不兼容2.3.4,因此这里仍然使用2.3.3版本. 可以自定义兼容处理,官方提供了文档:https://mp. ...

  3. Java String 去掉特殊字符之前的内容方法

    为了去除字符串中某个特殊字符之前(包括该特殊字符本身)的所有内容,我们可以使用Java中的String类的substring和indexOf方法.这里,我将给出一个完整的代码示例,该示例会找到字符串中 ...

  4. Ubuntu搭建ssh服务器

    Ubuntu安装后默认只有ssh客户端,即只能在Ubuntu内去连接其他ssh服务器,若想实现我们的Ubuntu被其他主机远程连接,则需要自己去安装ssh服务端. 安装 进入Ubuntu18.04,打 ...

  5. wiz 为知笔记服务器 docker 迁移爬坑指北

    本文主要是介绍 wiz 为知笔记服务器 docker 从旧服务器迁移到新服务器的步骤以及问题排查. 旧服务器升级 wiz docker 目的:保持和新服务器拉取的镜像版本一致. 官方只留了 wiz d ...

  6. Java异常详解(全文干货)

    介绍 Throwable Throwable 是 Java 语言中所有错误与异常的超类. Throwable 包含两个子类:Error(错误)和 Exception(异常),它们通常用于指示发生了异常 ...

  7. JVM笔记九-GC收集器日志信息学习

    在上一篇文章中,我们通过代码运行结果,查看到JVM的堆内存逻辑上分区是三部分,物理上分区是2部分,以及是新生代分区三部分,占比分布是8/1/1.而且我们还通过代码和堆JVM参数配置,制造出了OOM异常 ...

  8. 深入理解Argo CD工作原理

    1. ArgoCD 的架构 ArgoCD 是一个 Kubernetes 原生的持续交付工具,它通过监控 Git 仓库中的应用定义来自动部署应用到 Kubernetes 集群.其核心架构由以下几个关键组 ...

  9. Transformer应用于时序任务:综述《Transformers in Time Series: A Survey》

    2022年9月13日 21:28 摸鱼了一天,看看综述. 论文:Transformers in Time Series: A Survey GitHub: 阿里达摩院 2022的论文. 摘要 从两个角 ...

  10. Docker基本操作(镜像操作?容器操作?)(四)

    Docker 的基本原理我们已经了解了,也已经安装上了,接下来我们就一起来学习下 Docker 的常用操作,实际上主要就是 Docker CLI 的一些常用命令使用. 一.镜像操作 之前我们提到过 D ...