手写js new,new的过程到底发生了什么

在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!!

相关推荐
zhensherlock15 小时前
Protocol Launcher 系列:Beorg 高效任务管理的协议支持
前端·javascript·typescript·node.js·自动化·github·js
我命由我123452 天前
JavaScript 开发 - 获取函数名称、获取函数参数数量、获取函数参数名称
开发语言·前端·javascript·css·html·html5·js
爱上好庆祝2 天前
学习js的第四天
前端·css·学习·html·css3·js
zhensherlock4 天前
Protocol Launcher 系列:Tally 快速计数器的深度集成
前端·javascript·typescript·node.js·自动化·github·js
爱上好庆祝5 天前
学习js的第三天
前端·css·人工智能·学习·计算机外设·js
zhensherlock5 天前
Protocol Launcher 系列:Working Copy 文件操作与高级命令详解
javascript·git·typescript·node.js·自动化·github·js
zhensherlock6 天前
Protocol Launcher 系列:Working Copy 提交与同步全攻略
javascript·git·typescript·node.js·自动化·github·js
天若有情6736 天前
【开源推荐】form-validator-cn 轻量级中文表单校验库 | TS 零依赖、极简开箱即用
前端·npm·开源·node·js·表单校验
zhensherlock7 天前
Protocol Launcher 系列:Trello 看板管理的协议自动化
前端·javascript·typescript·node.js·自动化·github·js
珊瑚怪人10 天前
分享一个Edge浏览器播放H265 RTSP流的问题,涉及到ZLMediaKit、WebRTC
音视频·视频·js·zlmediakit·视频流处理