在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. MySQL 5.7 DDL 与 GH-OST 对比分析

    作者:来自 vivo 互联网存储研发团队- Xia Qianyong 本文首先介绍MySQL 5.7 DDL以及GH-OST的原理,然后从效率.空间占用.锁阻塞.binlog日志产生量.主备延时等方面 ...

  2. mybatis打印sql 转

    我们在使用mybatis开发过程中,经常需要打印sql以及输入输出,下面说一下mybatis结合log4j打印sql的. 1.添加mybatis配置 mybatis的日志打印方式比较多,SLF4J | ...

  3. 为什么用Vite框架?来看它的核心组件案例详解

    Vite 是一个前端构建工具,它以其快速的开发服务器和生产优化的打包器而闻名前端界,今天的内容,必须得唠唠 Vite 的关键能力,以下是 Vite 的核心组件分析,以及使用案例: 原理分析: Vite ...

  4. 我的微服务项目之IdentityServer4

     2021,祝大家新年快乐!!! 2021年了,新的一年应该有新的计划,我的计划是准备去学习微服务,所以我将我自己的博客项目拆分成了一个微服务项目,用来给自己学习,项目地址:http://www.tt ...

  5. ElasticSearch-hard插件及IK分词器安装

    ElasticSearch-hard插件及IK分词器安装 编辑 ​ 通过上一篇学习,我们学会了ElasticSearch的安装及访问到了如下页面: 编辑 ​ ElasticSearch-head插件安 ...

  6. (Ljava/lang/String;)Ljava/util/List;

    背景:原正常代码,更改类名后,重新运行 报错:(Ljava/lang/String;)Ljava/util/List; 解决:mvn clean 后 compile,再运行,正常

  7. IP服务正常,域名服务异常,报400 badrequest

    IP的情况下,访问接口都正常,使用域名访问,报错400 badrequest 经确认,ssl配置无问题,证书文件本身无问题 最后查出来原因,是域名格式的问题,原域名中包含_,需要修改为- 排查过程: ...

  8. 总结:redis 突然变慢

    用户量暴增,无法下单,凌晨的夜,静悄悄... 经过查找发现Redis. 获取不到连接资源,并且集群中的单台 Redis 连接量很高. 大量的流量没了 Redis 的缓存响应,直接打到了 MySQL,最 ...

  9. 一文了解svg之stroke属性

    属性 stroke-width SVG具有stroke-width定义笔触宽度的CSS属性. <svg width="500" height="120"& ...

  10. JavaScript Library – PhotoSwipe

    效果 前言 以前用过 lightbox2 和 fancyapps. lightbox2 已经没有维护了. fancyapps 改版好多次了. v2, v3 现在 v4 已经开始收费了. PhotoSw ...