JS基础源码之手写模拟new

JS基础源码之手写模拟new

  • 手写模拟new
    • 初步实现
    • 最终实现

手写模拟new

new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象类型之一。
我们先看看new实现了哪些功能:

function Person (name,age){this.name = name;this.age = age;this.habit = 'Games';
}
Person.prototype.strength = 80;
Person.prototype.sayYourName = function (){console.log('I am ', this.name);
}
var person = new Person('kin',18);
console.log(person.name);//kin
console.log(person.habit);//Games
console.log(person.strength);//80
person.sayYourName();// I am kin

我们可以看到,实例person可以:

  1. 访问到Otaku构造函数里的属性;
  2. 访问到Otaku.prototype中的属性;
    接下来,我们可以尝试着模拟一下:
    因为new是关键字,所以无法像bind函数一样直接覆盖,所以我们写一个函数,命名为objectFactory,来模拟new的效果,用的时候是这样的:
function Person(){...
}
//使用new
var person = new Person(...);
//使用objectFactory
var person = objectFactory(Person,...)

初步实现

因为new的结果是一个新的对象,所以在模拟实现的时候,我们也要建立一个新对象,假设这个对象叫obj,因为obj会具有Person构造函数里的属性,我们可以使用Person.apply(obj,arguments)来给obj添加新的属性。
然后,实例的proto属性会指向构造函数的prototype,也正是因为建立起这样的关系,实例可以访问原型上的属性。

//第一版代码
function objectFactory(){var obj = new Object();Constructor = [].shift.call(arguments);obj.__proto__ = Constructor.prototype;Constructor.apply(obj,arguments);return obj;
}

在这一版中,我们:

  1. 用new Object()的方式新建了一个对象obj;
  2. 取出第一个参数,就是我们要传入的构造函数。此外因为shift会修改原数组,所以arguments会被去除第一个参数;
  3. 将obj的原型指向构造函数,这样obj就可以访问到构造函数原型中的属性;
  4. 使用apply,改变构造函数this的指向到新建的对象,这样obj就可以访问到构造函数中的属性;
  5. 返回obj;
    测试下:
function Person (name,age){this.name = name;this,age = age;this,habit = 'Games';
}
Person.prototype.strength = 88;
Person.prototype.sayYourName = function(){console.log('I am',this.name);
}
function objectFactory(){var obj = new Object();Constructor = [].shift.call(arguments);obj.__proto__ = Constructor.prototype;Constructor.apply(obj,arguments);return obj;
};
var person = objectFactory(Person,'kin',17);
console.log(person.name);//kin
console.log(person.habit);//Games
console.log(person.strength);//88
person.sayYourName();// I am kin

最终实现

假如构造函数有返回值

function Person(name,age){this.strength = 90;this.age = age;return {name:name,habit:'Games'}
}
var person = new Person('kin',12);
console.log(person.name);//kin
console.log(person.habit);//Games
console.log(person.strength);//undefined
console.log(person.age);//undefined

在这个案例中,构造函数返回了一个对象,在实例person中只能访问返回的对象中的属性。
而且还要注意一点,在这里我们是返回一个对象,假如我们只是返回一个基本类型的值呢?
我们再看一个例子:

Function Person(name,age){this.strength = 60;this.age = age;return 'handsome boy';
}
var person = new Otaku('kin',12);
console.log(person.name);//undefined
console.log(person.age);//undefined
console.log(person.strength);//60
console.log(person.age);//18

这次尽管有返回值,但是相当于没有对返回值进行处理。
所以我们还需要判断返回的值是不是一个对象,如果是一个对象,我们就返回这个对象,如果没有,我们该返回什么就返回什么。

//最终版的代码
function objectFactory(){var obj = new Object();Constructor = [].shift.call(arguments);obj.__proto__ = Constructor.apply(obj,arguments);return typeof ret == 'object' ? ret : obj;
};

本文章可以参考JS基础之原型&原型链一起看,学习效果更佳哟~

好啦!简单的知识点就到这里啦休息一下奖励自己一下!
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/210015.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

开发猿的平平淡淡周末---2023/12/9

上周回顾 完成了遗留的开发任务,基本全部完成进一步了解了系统当时设计的原理熟悉了代码的重构 2023.12.9 天气晴 温度适宜 前言 小伙伴们大家好,时间很快,又来到了周末,也是一个平平淡淡的周末。上周只更了一篇博客...原…

渗透测试 | 渗透测试之信息收集

渗透测试(penetration test,pentest)是实施安全评估(即审计)的具体手段。 渗透测试可能是单独进行的一项工作,也可能是常规研发生命周期(例如,Microsoft SDLC)里 IT 安全…

Unicode编码解码

一、Unicode概述 Unicode是一种字符编码标准,旨在解决不同字符集之间的兼容性问题。它为全球所有语言提供了一种统一的编码方式,使得各种字符能够在计算机系统中正确显示和处理。Unicode字符集包含了世界上几乎所有的字符,包括中文字符、英文…

算法Day23 简单吃饭(0-1背包)

简单吃饭(0-1背包) Description Input Output Sample 代码 import java.util.Scanner; public class Main {public static void main(String[] args) {Scanner scanner new Scanner(System.in);int n scanner.nextInt();int total scanner.nextInt(…

高项备考葵花宝典-项目进度管理输入、输出、工具和技术(中,很详细考试必过)

项目进度管理的目标是使项目按时完成。有效的进度管理是项目管理成功的关键之一,进度问题在项目生命周期内引起的冲突最多。 小型项目中,定义活动、排列活动顺序、估算活动持续时间及制定进度模型形成进度计划等过程的联系非常密切,可以视为一…

情深不必纠缠

那一年,男孩女孩在万千人中相遇了。多年后女人的一封邮件,让男人与女人的灵魂相遇了。他们无缘夫妻,却发现彼此是灵魂的陪伴。不能携手相守,却懂得彼此的心灵。 有一天,女人告诉男人要回家了,问男人心里会不…

VMware安装Ubuntu20.04并使用Xshell连接虚拟机

文章目录 虚拟机环境准备重置虚拟网络适配器属性(可选)配置NAT模式的静态IP创建虚拟机虚拟机安装配置 Xshell连接虚拟机 虚拟机环境准备 VMware WorkStation Pro 17.5:https://customerconnect.vmware.com/cn/downloads/details?downloadGr…

网上下载的pdf文件,为什么不能复制文字?

不知道大家有没有到过这种情况?在网上下载的PDF文件打开之后,发现选中文字之后无法复制。甚至其他功能也都无法使用,这是怎么回事?该怎么办? 当我们发现文件打开之后,编辑功能无法使用,很可能是…

AlexNet

概念 过拟合:根本原因是特征维度过多,模型假设过于复杂,参数过多,训练数据过少,噪声过多,导致拟合的函数完美的预测训练集,但对新数据的测试集预测结果差。 过度的拟合了训练数据,而没有考虑到…

29、卷积 - 参数 padding 的作用

在卷积过程中,Padding(填充)是一个关键的概念,它对于保留输入信息和有效地处理边缘信息至关重要。 1、Padding是什么? Padding 指的是在输入图像的周围添加额外的像素值,用来以扩大输入图像的尺寸,这些额外填充的像素值通常设置为零,卷积操作在这个填充后的输入图像上…

ThinkPHP生活用品商城系统

有需要请加文章底部Q哦 可远程调试 ThinkPHP生活用品商城系统 一 介绍 此生活用品商城系统基于ThinkPHP框架开发,数据库mysql,前端bootstrap。系统分为用户和管理员。(附带配套设计文档) 技术栈:ThinkPHPmysqlbootstrapphpstudyvscode 二 …

MYSQL主从复制配置指引

MYSQL主从复制配置指引 1.前期准备 部署完主备数据库,初始化主备库表结构和数据。 2. 主库配置修改 修改主库配置文件etc/my.cnf,新增以下配置: #服务器 id,需唯一 server-id 1 #二进制文件存放路径 log-bin mysql-bin …

深入理解JavaScript的箭头函数

深入理解JavaScript的箭头函数 在ES6中,JavaScript引入了箭头函数的概念,它提供了一种更简洁的语法来定义匿名函数。虽然箭头函数看起来很简单,但它们在实际应用中有一些独特的特性和行为。让我们深入理解箭头函数并学习如何正确地使用它们。…

记账中心二开

系统预设了 这几种 FSubSystem 为子系统 T_VC_SubSystem 卡片显示的表 字段 FNeedRalteAccount 设置为1的话 ,需要与总账连用系统将去查找 系统状态控制表。 如果系统状态 没有配置这个子系统 将无法显示数据 select sysStaCtr.fid from T_BD_SystemStatusCt…

Java LeetCode篇-深入了解二叉树的经典解法(多种方式实现:构造二叉树)

🔥博客主页: 【小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍ 文章目录 1.0 从前序与中序遍历序列来构造二叉树 1.1 实现从前序与中序遍历序列来构造二叉树思路 1.2 代码实现从前序与中序遍历序列来构造二叉树 2.0 从中序与后序遍历序…

计算目标检测和语义分割的PR

需求描述 实际工作中,相比于mAP项目更加关心的是特定阈值下的precision和recall结果;由于本次的GT中除了目标框之外还存在多边形标注,为此,计算IoU的方式从框与框之间变成了mask之间; 本文的代码适用于MMDetection下的…

Java Web 学习之路(2) —— 概念、SpringBoot + MyBatis(controller+service+mapper)开发流程与过程梳理

文章目录 前言1. 常见的一些概念1.1 POJO(Plain Ordinary Java Object 简单Java对象)1.2 DAO和Mapper 2. Java的三层架构2.1 包的层级结构2.2 交互层 controller(用户界面、网页)jsp文件2.3 业务处理层 service2.4 Mapper层 3. 注…

2024 年甘肃省职业院校技能大赛信息安全管理与评估赛项规程

2024 年甘肃省职业院校技能大赛高职学生组电子与信息大类信息安全管理与评估赛项规程 一、赛项名称 赛项名称:信息安全管理与评估 赛项类别:团体赛 赛项归属:电子与信息大类 二、竞赛目的 极安云科专注技能竞赛,包含网络建设…

微信小程序css实现的联系客服动画样式

一 、效果 二、代码 wxml <view class"customer-service"><button class"btn" open-type"contact"></button><image class"pic" src"https://ts4.cn.mm.bing.net/th?idOIP-C.3SGSiRPuOU9uH5VNVOMPwgHaHa…

序列的Z变换(信号的频域分析)

1. 关于Z变换 2. 等比级数求和 3. 特殊序列的Z变换 4. 因果序列/系统收敛域的特点 5. 例题