深入理解new关键词,并手写实现
在JavaScript中,new
关键字用于创建一个新对象,并执行一些初始化操作。
与普通函数相比,构造函数并没有任何特别的地方,首字母大写只是我们约定的小规定,用于区分普通函数.
详解new关键字
new关键字让构造函数具有了与普通函数不同的许多特点,而new的过程中,执行了如下过程:
- 声明一个中间对象;
- 将该中间对象的原型指向构造函数的原型;
- 将构造函数的this,指向该中间对象;
- 返回该中间对象,即返回实例对象。
模拟new关键字
下面我们通过手写一个 New
函数来模拟 new
关键字的行为:
javascript
// 创建new函数
function New(fun) {
// 声明一个中间对象,该对象为最终返回的实例
var res = {};
if (func.prototype !== null) {
// 将实例的原型指向构造函数的原型
res.__proto__ = func.prototype;
}
}
// 创建一个构造函数
var Person = function (name, age) {
this.name = name;
this.age = age;
this.getName = function () {
return this.name;
};
}
// 将构造函数以参数形式传入
function New(func) {
// 声明一个中间对象,该对象为最终返回的实例
var res = {};
if (func.prototype !== null) {
// 将实例的原型指向构造函数的原型
res.__proto__ = func.prototype;
}
// ret为构造函数执行的结果,这里通过apply,将构造函数内部的this指向修改为指向res,即为实例对象
var ret = func.apply(res, Array.prototype.slice.call(arguments, 1));
// 当我们在构造函数中明确指定了返回对象时,那么new的执行结果就是该返回对象
if ((typeof ret === 'object' || typeof ret === 'function') && ret !== null) {
return ret;
}
// 如果没有明确指定返回对象,则默认返回res,这个res就是实例对象
return res;
}
// 通过new声明创建实例,这里的p1,实际接收的正是new中返回的res
var p1 = New(Person, 'tom', 20);
console.log(p1.getName());
// 当然,这里也可以判断出实例的类型了
console.log(p1 instanceof Person); // true
代码解释
- 中间对象的创建:使用 var res = {} 创建一个空对象,作为后续操作的基础。
- 原型链的设置:通过 res.proto = func.prototype 将中间对象的原型指向构造函数的原型,确保实例能继承原型上的属性和方法。
- this 绑定与函数执行:使用 func.apply(res, Array.prototype.slice.call(arguments, 1)) 将构造函数的 this 绑定到中间对象 res 上,并传入剩余参数执行构造函数。
- 返回值判断:检查构造函数的返回值,如果是对象或函数且不为 null,则返回该返回值;否则返回中间对象 res。
本文标签:
本文链接:
https://vscing.com/article/70.html
版权声明:
本文由vscing原创发布,转载请遵循《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权
目录
标签
文章榜