一、如何实现一个new
1. 了解new 运算符
new运算符创建一个用户定义的对象类型的实例 或 具有构造函数的内置对象的实例。
new关键字会进行如下操作:
- 创建一个空对象
{}; - 链接该对象(设置该对象的constructor)到另一个对象(原型对象上);
- 将步骤1新创建的对象作为this的上下文(该对象被绑定为this);
- 如果该函数没有返回对象,则返回this。
2. new Foo(...)执行时,会发生什么?
- 一个继承自Foo.prototype的新对象被创建
- 使用指定的参数调用构造函数Foo,并将 this 绑定到新创建的对象。
- new Foo 等同于 new Foo(),也就是没有指定参数列表,Foo 不带任何参数调用的情况。
- 由构造函数返回的对象就是 new 表达式的结果。如果构造函数没有显式返回一个对象,则使用步骤1创建的对象。(一般情况下,构造函数不返回值,但是用户可以选择主动返回对象,来覆盖正常的对象创建步骤)
3.自己实现new
function myNew() {
// 构造函数就是我们传入的第一个参数。由于arguments是类数组,我们不能直接使用shift方法,我们可以使用call来调用Array上的shift方法,获取constr
var constr = Array.prototype.shift.call(arguments);
// 创建新对象,并且新对象可以使用构造函数的原型
var obj = Object.create(constr.prototype);
// 执行构造函数中的代码,为这个新对象添加属性
var result = constr.apply(obj, arguments);
// 如果返回的是undefined,null以及基本类型的时候,都会返回新的对象;而只有返回对象的时候,才会返回构造函数的返回值。
// 如果构造函数有返回值,则返回;否则则默认返回新对象
return result instanceof Object? result : obj;
}
function Person(name){
this.name = name
}
//验证:
var P2 = myNew(Person, "小名")
console.log(P2.name)//小名