前端百题斩【018】——从验证点到手撕new操作符

简介: 前端百题斩【018】——从验证点到手撕new操作符

18.1 基础



new的作用是通过构造函数来创建一个实例对象,该实例与原型和构造函数之间的关系如下图所示:

640.png



18.2 new过程中发生了什么


当一个构造函数new的过程到底发生了什么?简要概述主要分为以下几个步骤:

  1. 一个新对象被创建;


  1. 该对象的__ proto __属性指向该构造函数的原型,即Fn.prototype;


  1. 将执行上下文(this)绑定到新创建的对象中;


  1. 如果构造函数有返回值(对象或函数),那么这个返回值将取代第一步中新创建的对象。


new真的做了这几步吗?秉承着“实践是检验真理的唯一标准”的原则,下面将这几个关键点进行逐一验证。


function Fun() {
    this.a = 10;
    this.b = 20;
    this.method1 = () => {
        return this.a + this.b;
    }
    this.method2 = () => {
        return this;
    }
}
Fun.prototype = {
    method2: () => {
        console.log('原型上的method1被访问');
    }
}

18.2.1 验证点1——新对象被创建


验证点1是新对象被创建,其实这个里面有两层含义:


  1. new之后返回的内容是一个对象

const fun = new Fun();
console.log(fun); //  { a: 10, b: 20, method1: [Function] }
console.log(typeof(fun)); // object

通过打印其内容,并通过typeof进行验证,其返回内容确实是一个对象。


  1. 每次返回的都是一个新创建的对象


const fun1 = new Fun();
const fun2 = new Fun();
console.log(fun1 === fun2); // false

通过创建两个实例,通过判断两个实例不相等,则证明确实每次返回的是一个新的对象。


18.2.2 验证点2——该对象可访问原型上的属性和方法


验证点2是新创建的实例可访问原型上的属性和方法,验证该关键点只需要访问原型上的方法即可实现,若原型上的方法能够被正常访问,则表示该验证点通过,负责不通过。


const fun3 = new Fun();
fun3.method3(); // 原型上的method3被访问

通过验证,原型上的方法确实能够被访问。


18.2.3 验证点3——this指向


验证this指向只需要将this指向打印出来即可。


const fun4 = new Fun();
console.log(fun4.method2()); // { a: 10, b: 20, method1: [Function], method2: [Function] }
console.log(fun4.method2() === fun4); // true

18.2.4 验证点4——构造函数有返回值的处理逻辑


一个函数的返回值可以有多种,例如:string、boolean、number、Object、function等,下面我们验证一些内容,看构造函数有不同的返回值,其实例为何值。

  1. 返回值为string


function Fun() {
    this.a = 10;
    this.b = 20;
    return 'test';
}
Fun.prototype = {
    method: () => {
        console.log('原型上的method被访问');
    }
}
const fun = new Fun();
console.log(fun); // { a: 10, b: 20 }

观察其最终结果,字符串没有没正常返回,返回值是一个新的实例。


  1. 返回值为Object


function Fun() {
    this.a = 10;
    this.b = 20;
    return {
        c: 30
    };
}
Fun.prototype = {
    method: () => {
        console.log('原型上的method被访问');
    }
}
const fun = new Fun();
console.log(fun); // { c: 30 }

观察其结果,返回值是函数中返回的对象,则表征当构造函数返回值为对象时,会返回其对象,不返回实例化后的内容。


  1. 返回值为function


function Fun() {
    this.a = 10;
    this.b = 20;
    return function() {
        this.d = 40;
    };
}
Fun.prototype = {
    method: () => {
        console.log('原型上的method被访问');
    }
}
const fun = new Fun();
console.log(fun); // [Function]

返回函数的效果和返回对象的效果一致。


通过不断尝试总结,可以得出以下结论:


  1. 构造函数的返回值为基本类型,其返回值是实例化后的对象,不受返回值的影响;
  2. 构造函数的返回值是引用类型,其返回值即为new之后的返回值。


18.3 实现一个new



介绍了这么多,已经理解了new时发生的事情并经过了验证,下面就手动实现一个自己的new函数。


function myNew(Fn, ...args) {
    // 一个新的对象被创建
    const result = {};
    // 该对象的__proto__属性指向该构造函数的原型
    if (Fn.prototype !== null) {
        Object.setPrototypeOf(result, Fn.prototype);
    }
    // 将执行上下文(this)绑定到新创建的对象中
    const returnResult = Fn.apply(result, args);
    // 如果构造函数有返回值(对象或函数),那么这个返回值将取代第一步中新创建的对象。
    if ((typeof returnResult === 'object' || typeof returnResult === 'function') && returnResult !== null) {
        return returnResult;
    }
    return result;
}

小试牛刀


function Fun() {
    this.a = 10;
    this.b = 20;
}
Fun.prototype = {
    method: () => {
        console.log('原型上的method被访问');
    }
}
const fun1 = new Fun();
console.log(fun1); // { a: 10, b: 20 }
const fun2 = myNew(Fun);
console.log(fun2); // { a: 10, b: 20 }


相关文章
|
前端开发 测试技术
【前端验证】记录将发包量作为传参以加速debug的环境优化记录
【前端验证】记录将发包量作为传参以加速debug的环境优化记录
|
5月前
|
前端开发 开发者
new操作符背后的秘密:揭开Web前端对象创建的神秘面纱!
【8月更文挑战第23天】在Web前端开发中,`new`操作符是创建对象实例的核心。本文以`Person`构造函数为例,通过四个步骤解析`new`操作符的工作原理:创建空对象、设置新对象原型、执行构造函数并调整`this`指向、判断并返回最终对象。了解这些有助于开发者更好地理解对象实例化过程,从而编写出更规范、易维护的代码。
50 0
|
2月前
|
存储 前端开发 JavaScript
前端:new关键字的作用
在JavaScript中,`new`关键字用于创建构造函数或类的新实例。使用`new`时,会自动创建一个空对象,并将其绑定到函数内的`this`,执行构造函数中的代码后返回该对象。这使得对象可以继承构造函数的属性和方法。
|
3月前
|
前端开发 数据安全/隐私保护
angular前端基本页面验证
angular前端基本页面验证
40 1
|
3月前
|
存储 前端开发 Java
验证码案例 —— Kaptcha 插件介绍 后端生成验证码,前端展示并进行session验证(带完整前后端源码)
本文介绍了使用Kaptcha插件在SpringBoot项目中实现验证码的生成和验证,包括后端生成验证码、前端展示以及通过session进行验证码校验的完整前后端代码和配置过程。
464 0
验证码案例 —— Kaptcha 插件介绍 后端生成验证码,前端展示并进行session验证(带完整前后端源码)
|
5月前
|
前端开发 JavaScript
这篇文章介绍了如何使用form表单结合Bootstrap格式将前端数据通过action属性提交到后端的servlet,包括前端表单的创建、数据的一级和二级验证,以及后端servlet的注解和参数获取。
这篇文章介绍了使用AJAX技术将前端页面中表单接收的多个参数快速便捷地传输到后端servlet的方法,并通过示例代码展示了前端JavaScript中的AJAX调用和后端servlet的接收处理。
这篇文章介绍了如何使用form表单结合Bootstrap格式将前端数据通过action属性提交到后端的servlet,包括前端表单的创建、数据的一级和二级验证,以及后端servlet的注解和参数获取。
|
5月前
|
前端开发 开发者 UED
数据校验的艺术:揭秘JSF如何将前端与后端验证合二为一,打造无缝用户体验
【8月更文挑战第31天】JavaServer Faces(JSF)是构建企业级Web应用的Java规范,提供了丰富的组件和API,便于快速搭建用户界面。JSF验证框架基于JavaBean验证API(JSR 303/JSR 380),利用注解如`@NotNull`、`@Size`等在模型类上定义验证规则,结合前端的`<h:inputText>`和`<h:message>`标签展示错误信息。
58 0
|
5月前
|
前端开发 数据库 Python
中后台前端开发问题之验证用户提供的uid和token的有效性如何解决
中后台前端开发问题之验证用户提供的uid和token的有效性如何解决
32 0
|
7月前
|
存储 前端开发 搜索推荐
Web前端网站(一) - 登录页面及账号密码验证
页面背景动态是烟花和文字特效与缓缓下落的雪花相结合,在登录表单的旁边还有五个白色光圈以不规则的方式环绕,当鼠标靠近时,会发出彩色的光芒~~~
115 1
Web前端网站(一) - 登录页面及账号密码验证
|
7月前
|
前端开发 JavaScript
阿里云验证码2.0 验证时报错 前端页面获取的验证参数有问题,动态JS加载失败,请问怎么解决啊?急,急,急。
用户反馈校验时遇到错误,日志显示验证码参数获取异常。采用无痕验证,失败后,返回`{captchaResult:false,bizResult:false}`,未触发滑块二次验证。

热门文章

最新文章