当前位置:网站首页>Simulation implementation of new of Js handwritten function
Simulation implementation of new of Js handwritten function
2022-08-01 12:32:00 【Name is not ready yet】
JavaScriptIn-depth article twelfth in the series,通过new的模拟实现,Take everyone to open to usenewGet the truth of the constructor instance
new
一句话介绍 new:
new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象类型之一
Maybe a little hard to understand,我们在模拟 new 之前,先看看 new 实现了哪些功能.
举个例子:
// Otaku 御宅族,简称宅
function Otaku (name, age) {
this.name = name;
this.age = age;
this.habit = 'Games';
}
// 因为缺乏锻炼的缘故,身体强度让人担忧
Otaku.prototype.strength = 60;
Otaku.prototype.sayYourName = function () {
console.log('I am ' + this.name);
}
var person = new Otaku('Kevin', '18');
console.log(person.name) // Kevin
console.log(person.habit) // Games
console.log(person.strength) // 60
person.sayYourName(); // I am Kevin
从这个例子中,我们可以看到,实例 person 可以:
- 访问到 Otaku 构造函数里的属性
- 访问到 Otaku.prototype 中的属性
接下来,We can try to simulate it.
因为 new 是关键字,所以无法像 bind Functions are directly overridden,所以我们写一个函数,命名为 objectFactory,来模拟 new 的效果.This is how it is used:
function Otaku () {
……
}
// 使用 new
var person = new Otaku(……);
// 使用 objectFactory
var person = objectFactory(Otaku, ……)
初步实现
分析:
因为 new 的结果是一个新对象,所以在模拟实现的时候,We also create a new object,假设这个对象叫 obj,因为 obj 会具有 Otaku 构造函数里的属性,Consider the example of classical inheritance,我们可以使用 Otaku.apply(obj, arguments)来给 obj 添加新的属性.
在 JavaScript Dive into the first part of the series,We talked about prototypes and prototype chains,我们知道实例的 __proto__ 属性会指向构造函数的 prototype,It is precisely because of the establishment of such a relationship,Instances can access properties on the prototype.
现在,We can try to write the first edition:
// 第一版代码
function objectFactory() {
var obj = new Object(),
Constructor = [].shift.call(arguments);
obj.__proto__ = Constructor.prototype;
Constructor.apply(obj, arguments);
return obj;
};
在这一版中,我们:
- 用new Object() 的方式新建了一个对象 obj
- 取出第一个参数,就是我们要传入的构造函数.此外因为 shift 会修改原数组,所以 arguments 会被去除第一个参数
- 将 obj 的原型指向构造函数,这样 obj 就可以访问到构造函数原型中的属性
- 使用 apply,改变构造函数 this 的指向到新建的对象,这样 obj 就可以访问到构造函数中的属性
- 返回 obj
更多关于:
原型与原型链,可以看《JavaScript深入之从原型到原型链》
apply,可以看《JavaScript深入之call和apply的模拟实现》
经典继承,可以看《JavaScript深入之继承》
Copy the code below,到浏览器中,We can do a test:
function Otaku (name, age) {
this.name = name;
this.age = age;
this.habit = 'Games';
}
Otaku.prototype.strength = 60;
Otaku.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(Otaku, 'Kevin', '18')
console.log(person.name) // Kevin
console.log(person.habit) // Games
console.log(person.strength) // 60
person.sayYourName(); // I am Kevin
[]~( ̄▽ ̄)~**
Return value effect implementation
接下来我们再来看一种情况,If the constructor has a return value,举个例子:
function Otaku (name, age) {
this.strength = 60;
this.age = age;
return {
name: name,
habit: 'Games'
}
}
var person = new Otaku('Kevin', '18');
console.log(person.name) // Kevin
console.log(person.habit) // Games
console.log(person.strength) // undefined
console.log(person.age) // undefined
在这个例子中,The constructor returns an object,在实例 person 中只能访问返回的对象中的属性.
And one more thing,Here we are returning an object,What if we just returned a value of a primitive type?
再举个例子:
function Otaku (name, age) {
this.strength = 60;
this.age = age;
return 'handsome boy';
}
var person = new Otaku('Kevin', '18');
console.log(person.name) // undefined
console.log(person.habit) // undefined
console.log(person.strength) // 60
console.log(person.age) // 18
The result is completely reversed,This time despite the return value,But it is equivalent to no return value for processing.
So we also need to determine whether the returned value is an object,如果是一个对象,我们就返回这个对象,如果没有,我们该返回什么就返回什么.
Let's look at the second version of the code,Also the last version of the code:
// 第二版的代码
function objectFactory() {
var obj = new Object(),
Constructor = [].shift.call(arguments);
obj.__proto__ = Constructor.prototype;
var ret = Constructor.apply(obj, arguments);
return typeof ret === 'object' ? ret : obj;
};
边栏推荐
- R语言ggplot2可视化:使用ggpubr包的ggscatter函数可视化散点图、使用xscale函数指定X轴坐标轴度量调整方式、设置x轴坐标为scientific使用科学计数法显示坐标值
- SQL函数 SQUARE
- MarkDown公式指导手册
- Aeraki Mesh Joins CNCF Cloud Native Panorama
- 安装apex报错
- 判断JS数据类型的四种方法
- 如何成功通过 CKA 考试?
- 如何设计一个分布式 ID 发号器?
- 【云享新鲜】社区周刊·Vol.73- DTSE Tech Talk:1小时深度解读SaaS应用系统设计
- How much do you know about Amazon reviews?
猜你喜欢
随机推荐
R语言ggplot2可视化:使用ggpubr包的ggscatter函数可视化散点图、使用xscale函数指定X轴坐标轴度量调整方式、设置x轴坐标为scientific使用科学计数法显示坐标值
迁移学习冻结网络的方法:
千万级乘客排队系统重构&压测方案——总结篇
.NET analyzes the LINQ framework in depth (three: the elegant prelude of LINQ)
Qt获取文件夹下所有文件
Favorites|Mechanical Engineer Interview Frequently Asked Questions
蔚来又一新品牌披露:产品价格低于20万
Grafana9.0发布,Prometheus和Loki查询生成器、全新导航、热图面板等新功能!
MVVM响应式
Js手写函数之new的模拟实现
大中型网站列表页翻页过多怎么优化?
那些利用假期学习的职场人,后来都怎么样了?
Visualization of lag correlation of two time series data in R language: use the ccf function of the forecast package to draw the cross-correlation function, and analyze the lag correlation according t
SQL函数 STR
How to use DevExpress controls to draw flowcharts?After reading this article, you will understand!
深入理解 Istio —— 云原生服务网格进阶实战
如何将第三方服务中心注册集成到 Istio ?
程序员的自我修养
一文带你读懂云原生、微服务与高可用
C#/VB.NET 将PPT或PPTX转换为图像









