JS基础源码之手写模拟new

news/2025/3/31 10:55:54/

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.ppmy.cn/news/1263882.html

相关文章

ArkUI组件

目录 一、概述 声明式UI 应用模型 二、常用组件 1、Image:图片展示组件 示例 配置控制授权申请 2、Text:文本显示组件 示例 3、TextInput:文本输入组件 示例 4、Button:按钮组件 5、Slider:滑动条组件 …

【vtkWidgetRepresentation】第七期 vtkImplicitPlaneRepresentation

很高兴在雪易的CSDN遇见你 前言 本文分享vtkImplicitPlaneRepresentation源码剖析,及相关的实例,该接口主要用于切割交互,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞关注,小易会继续努力分享,一起…

Django模型

一、model 文件中的类的建立: 对应的是数据库中的每个表,类中有什么字段,表就会对应的生成某个字段,主键id字段会自己生成; 数据库中的文件获取:只能通过模型类.objects来获取,不能通过模型类…

华为OD机试真题-执行任务赚积分-2023年OD统一考试(C卷)

题目描述: 现有N个任务需要处理,同一时间只能处理一个任务,处理每个任务所需要的时间固定为1。 每个任务都有最晚处理时间限制和积分值,在最晚处理时间点之前处理完成任务才可获得对应的积分奖励。 可用于处理任务的时间有限,请问在有限的时间内,可获得的最多积分。 输入…

mybatis的快速入门以及spring boot整合mybatis(二)

需要用到的SQL脚本: CREATE TABLE dept (id int unsigned PRIMARY KEY AUTO_INCREMENT COMMENT ID, 主键,name varchar(10) NOT NULL UNIQUE COMMENT 部门名称,create_time datetime DEFAULT NULL COMMENT 创建时间,update_time datetime DEFAULT NULL COMMENT 修改…

LLM之Agent(五)| AgentTuning:清华大学与智谱AI提出AgentTuning提高大语言模型Agent能力

​论文地址:https://arxiv.org/pdf/2310.12823.pdf Github地址:https://github.com/THUDM/AgentTuning 在ChatGPT带来了大模型的蓬勃发展,开源LLM层出不穷,虽然这些开源的LLM在各自任务中表现出色,但是在真实环境下作…

uniapp基于u-grid-item九宫格实现uCharts秋云图表展示

uniapp基于uView的UI组件u-grid-item九宫格实现uCharts秋云可视化图表展示 这里使用uView的u-grid-item九宫格组件去显示图标排列 九宫格可以做成多列&#xff0c;移动设备上可以通过左右滑动进行展示 <template><div><div style"text-align: center;font…

语言模型GPT与HuggingFace应用

受到计算机视觉领域采用ImageNet对模型进行一次预训练&#xff0c;使得模型可以通过海量图像充分学习如何提取特征&#xff0c;然后再根据任务目标进行模型微调的范式影响&#xff0c;自然语言处理领域基于预训练语言模型的方法也逐渐成为主流。以ELMo为代表的动态词向量模型开…