在传统的面向对象语言中,“构造函数”是类中的一些特殊方法,使用new初始化时会调用类中的构造函数,通常形式为:
obj=new MyClass(...)
而JavaScript中的new操作符,其实与面向类的语言完全不同。js中的构造函数只是一些使用new操作符是被调用的函数,它们并不属于某个类,也不会实例化一个对象,它们只是普通函数而已。所以包括内置对象函数(如Number(…))在内的所用函数都可以用new来调用。
了解了这些,我们就可以来具体看看new到底做了什么。一般分为如下几个步骤:
1、创建一个空对象
2、这个对象会被执行[[Prototype]]连接
3、这个对象会绑定到函数调用的this上
4、如果函数没有返回其他对象,那么new表达式中的函数会自动返回这个新对象
具体代码实现如下:
function newFun(P) {
let obj={}
let params=Array.prototype.slice.call(arguments,1)
console.log(params)
obj.__proto__=P.prototype //或者 let obj=Object.create(P.prototype)
P.prototype.constructor = P; //将P的构造函数强制指向回来,这里其实可以不用
P.apply(obj,params) //this指向新对象
return obj
}
这里详细解释this指向,P.apply(obj,params)相当于如下代码:
obj.fn = this; //这里的this就是调用P函数
obj.fn(); //相当于执行P函数,P函数里的this指向调用它的obj,所以obj可以拿到P中的属性
delete obj.fn;
最后验证一下:
let person1=newFun(Person,'paul',25,'doctor')
alert(person1instanceof Person); //true
alert(person1.__proto__.constructor === Person); //true
参考文档
- 《你不知道的JavaScript上卷》