今天我们来聊一聊JavaScript中的new
操作符,它用于创建一个给定构造函数的实例对象。话不多说,我们来看下面的这一段代码:
function Person() {
this.name = 'John';
this.age = 18;
}
const p = new Person();
console.log(p,p.constructor); // Person { name: 'John', age: 18 } [Function: Person]
我们发现,构造函数Person
上面的属性,实例对象p
也能够访问,并且,构造函数原型对象(prototype
)上的constructor
属性,它也能够访问。
这能够说明什么呢?
- 构造函数的
this
指向了实例对象 - 实例对象的
__proto__
指向了构造函数的prototype
再来看这一段代码:
function Person() {
this.name = 'John';
this.age = 25;
return {
hobby: 'coding'
}
}
const p = new Person();
console.log(p,p.constructor); // { hobby: 'coding' } [Function: Object]
我们会发现,这里的实例对象p
好像又不能访问构造函数Person
上面的属性了,而只能访问构造函数返回的那个对象。那么如果返回值不是对象,又会出现什么结果呢?
function Person() {
this.name = 'John';
this.age = 25;
return 123
}
const p = new Person();
console.log(p,p.constructor); // Person { name: 'John', age: 25 } [Function: Person]
我们会发现,如果不是返回一个对象的话,那和没有返回值是一样的。其实是这样的,new
操作符在创建实例对象的时候干了这么一件事。
- 创建一个空对象
- 将该对象的__proto__指向构造函数的prototype
- 执行构造函数,并将构造函数的this指向该空对象
- 如果构造函数具有返回值,并且返回值是一个对象,那么返回该对象,否则返回我们刚开始创建的空对象。
如下便是一个简单的new
的实现
function myNew(fn, ...args) {
// 创建一个新对象
const obj = {}
// 构造函数的prototype 指向 实例对象的__proto__
obj.__proto__ = fn.prototype
// 将构造函数的this指向obj,并执行构造函数
const result = fn.call(obj, ...args)
// 如果返回值是对象,返回对象,否则返回新对象
return typeof result === 'object' && typeof result !== null ? result : obj
}
今天的分享就到这,如有不对的地方,欢迎大家指正。
原文链接:https://juejin.cn/post/7335463274619977778 作者:小白234