持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第14天,点击查看活动详情
在平时工作和面试经常会被问道,“new一个新对象的过程,发生了什么?”关于这个问题,我们先从构造函数讲起,再具体详细讲解new一个对象的具体流程,最后再通过代码简单手写一个new函数。
构造函数
在ES6之前,js并没有类的概念,对象并不是基于类去创建的,而是用构造函数的来定义的。如:
function Person(name,age){
this.name = name;
this.age = age;
}
let pr = new Person('vivi',23);
由此可见,构造函数是一种特殊的函数,可以用来定义对象和它们的特征,通常和new一起使用。 需要注意的是:当构造函数用于创建对象时,其首字母要大写。
new一个新对象
回到最初的问题,我们来对new一个对象做一下的简单分解动作:首先需要分配对象的内存空间,然后初始化对象,最后设置引用指向分配的内存地址。
具体的,我们来看调用new时,主要做了哪些事情:
- 在内存中创建一个新的空对象
- 将空对象的_proto_指向构造函数的prototype,并将构造函数的this指向这个新创建的空对象
- 执行构造函数,为这个对象添加属性和方法。
- 最后,查看构造函数本身的返回结果:如果有return 对象,则直接返回这个对象,如果没有返回值或者返回的是一个原始值,则浏览器默认会将新创建的对象实例返回。
根据以上的步骤,我们可以手写一个简单的new函数,如下:
function createNew(fn,..args){
const obj={}; //创建一个空对象
obj.__proto__ = fn.prototype; //空对象的_propto_指向构造函数的prototype
const res = fn.apply(obj,args);//构造函数的this指向这个新创建的空对象
return typeof res === 'object'?res:obj;//有返回值则返回返回值,没有则返回新对象
}
const pr = createNew(Person,'vivi',23);