当前位置: 首页 > article >正文

第二话: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.kler.cn/a/383372.html

相关文章:

  • 普通人没钱又没能力的话,那就踏实学一门手艺
  • 靠Python真的能实现经济自由,学会了你也可以
  • 深入理解网络协议:OSPF、VLAN、NAT与ACL详解
  • 基础算法——排序算法(冒泡排序,选择排序,堆排序,插入排序,希尔排序,归并排序,快速排序,计数排序,桶排序,基数排序,Java排序)
  • 开源协议类型及长安链开源协议介绍
  • ES管理工具Cerebro 0.8.5 Windows版本安装及启动
  • 如何将自己的程序文件上传至Github
  • Android——从相机/相册获取图片
  • 无人机避障——大疆与Airsim中的角速度信息订阅获取
  • [免费]SpringBoot+Vue(高校)学籍管理系统【论文+源码+SQL脚本】
  • 【原创】java+ssm+mysql收纳培训网系统设计与实现
  • 【Ajax】跨域
  • StarRocks 在 Shopee 数据产品的实践
  • 应用链风口下,一键发链该如何选择?
  • 数据结构模拟题[十]
  • Java项目实战II基于Java+Spring Boot+MySQL的智能推荐的卫生健康系统(开发文档+数据库+源码)
  • 编译google protobuf项目,生成相应语言的dll文件
  • React中类组件和函数组件的理解和区别
  • 微信小程序 uniapp+vue老年人身体监测系统 acyux
  • 域名申请网站需要了解的事项
  • springbootHR Nexus人力资源管理系统-计算机毕业设计源码23519
  • 背包九讲——背包问题求方案数
  • ssm032基于Java的汽车客运站管理系统的设计与实现+jsp(论文+源码)_kaic
  • 企业微信会话存档引用com.tencent.wework.Finance出错?
  • 新书速览|Java网络爬虫精解与实践
  • linux firewall 常用命令汇总