JS基础源码之手写模拟new

这篇具有很好参考价值的文章主要介绍了JS基础源码之手写模拟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基础之原型&原型链一起看,学习效果更佳哟~

好啦!简单的知识点就到这里啦休息一下奖励自己一下!
JS基础源码之手写模拟new,javascript,前端,原型模式
JS基础源码之手写模拟new,javascript,前端,原型模式
JS基础源码之手写模拟new,javascript,前端,原型模式文章来源地址https://www.toymoban.com/news/detail-756558.html

到了这里,关于JS基础源码之手写模拟new的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 〖大前端 - 基础入门三大核心之JS篇㉔〗- JavaScript 的数组的常用方法 (一)

    当前子专栏 基础入门三大核心篇 是免费开放阶段 。 推荐他人订阅,可获取扣除平台费用后的35%收益,文末名片加V! 说明:该文属于 大前端全栈架构白宝书专栏, 目前阶段免费开放 , 购买任意白宝书体系化专栏可加入 TFS-CLUB 私域社区。 福利:除了通过订阅\\\"白宝书系列专

    2024年02月07日
    浏览(56)
  • 〖大前端 - 基础入门三大核心之JS篇⑰〗- JavaScript的流程控制语句「while循环语句」

    当前子专栏 基础入门三大核心篇 是免费开放阶段 。 推荐他人订阅,可获取扣除平台费用后的35%收益,文末名片加V! 说明:该文属于 大前端全栈架构白宝书专栏, 目前阶段免费开放 , 购买任意白宝书体系化专栏可加入 TFS-CLUB 私域社区。 福利:除了通过订阅\\\"白宝书系列专

    2024年02月04日
    浏览(94)
  • 【JavaScript】手撕前端面试题:手写Object.create | 手写Function.call | 手写Function.bind

    🖥️ NodeJS专栏:Node.js从入门到精通 🖥️ 博主的前端之路(源创征文一等奖作品):前端之行,任重道远(来自大三学长的万字自述) 🖥️ TypeScript知识总结:TypeScript从入门到精通(十万字超详细知识点总结) 🧑‍💼个人简介:大三学生,一个不甘平庸的平凡人🍬 👉

    2024年02月21日
    浏览(78)
  • JavaScript获取时间(js中的new Date(),获取前7天时间)

    简述:我们在写Echarts的时候,难免会用到js中的new Date(),用来获取时间, 今天就来分享下它的用法,顺便做下笔记。 关于new Date()的一些js方法: 输出: 1、 获取前一段时间的日期 难点: 这里用到了setDate()方法,该方法用于实现日期的相加减,它接收一个整数,如果这个整

    2024年02月09日
    浏览(80)
  • 〖大前端 - 基础入门三大核心之JS篇⑱〗- JavaScript的流程控制语句「break 和 continue语句」

    当前子专栏 基础入门三大核心篇 是免费开放阶段 。 推荐他人订阅,可获取扣除平台费用后的35%收益,文末名片加V! 说明:该文属于 大前端全栈架构白宝书专栏, 目前阶段免费开放 , 购买任意白宝书体系化专栏可加入 TFS-CLUB 私域社区。 福利:除了通过订阅\\\"白宝书系列专

    2024年02月05日
    浏览(57)
  • Spring手写模拟源码篇(你值得拥有)

    下面是本文章关于Spring底层原理的章节 类-》推断构造方法-》根据构造方法创建普通对象-》依赖注入(@Autowired等进行属性注入)-》初始化前(@PostConstruct)-初始化(InitializingBean)-》初始化后(AOP)-》代理对象(没有开启AOP就会把普通对象放入单例池)-》放入单例池-》Bean对象

    2024年02月01日
    浏览(39)
  • 〖大前端 - 基础入门三大核心之JS篇⑯〗- JavaScript的流程控制语句「for循环语句及算法题」

    当前子专栏 基础入门三大核心篇 是免费开放阶段 。 推荐他人订阅,可获取扣除平台费用后的35%收益,文末名片加V! 说明:该文属于 大前端全栈架构白宝书专栏, 目前阶段免费开放 , 购买任意白宝书体系化专栏可加入 TFS-CLUB 私域社区。 福利:除了通过订阅\\\"白宝书系列专

    2024年02月07日
    浏览(51)
  • web前端【3】JS基础-轮播图【JavaScript、定时器、鼠标动作、自动轮播、增加和减少li列表】

    一、实验题目: 轮播图 二、实验内容简介 1.整体布局:图片、左右按钮、数字列表、添加删除按钮 2、左右箭头滚动 3、小圆点滚动 4、自动轮播 5、鼠标动作:指向和离开 6、添加与删除 三、实验过程 1. 需求分析 整体布局:设计一个轮播图,中间部分为自动轮播的图片展示

    2024年02月04日
    浏览(57)
  • JavaScript中的时间日期函数new Date()(JS中5种获取时间戳的函数)

    简介: JavaScript 中的 new Date() 方法用于创建一个新的 Date 对象,该对象表示当前日期和时间。Date 对象提供了许多方法和属性,可以用于获取和设置日期和时间信息。 new Date([year, month, day, hour, minute, second, millisecond]) 其中,每个参数都是可选的。如果没有指定参数,则 new Dat

    2024年02月04日
    浏览(73)
  • SpringMvc拦截器和手写模拟SpringMvc工作流程源码详解

    目录 1. SpringMvc简介 1.1 什么是MVC 1.2 什么是SpringMvc 1.3 SpringMvc 能干什么 1.4 SpringMvc 工作流程 2. SpringMvc拦截器和过滤器 2.1 拦截器 2.1.1 拦截器作用 2.1.2 拦截器和过滤器的区别 2.1.3 拦截器方法说明 2.1.4 多个拦截器执行顺序 2.1.5 自定义拦截器 2.2 过滤器(附加) 3. 手写模拟Spri

    2024年02月09日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包