1.创建一个新对象;
2.将新对象的原型指向构造函数的原型链;
3.将构造函数的this指向新对象,并将初始化时的参数传入;
4.判断构造函数中是否返回了其他对象,如果有返回对象,则将构造函数的返回对象返回;否则返回新对象;
// 构造函数1,有return
function Test1 (options) {
return {
name: '哈哈',
opt: options || ''
};
}
// 构造函数2,属性和方法在原型和构造函数上。
function Test2 (options) {
this.width = 120;
this.opt = options || '';
}
Test2.prototype.height = 123;
function _new () {
// 创建一个新对象;
var newFunc = {};
// 构造函数初始化时传入的参数
var args = Array.prototype.slice.call(arguments, 1);
// 默认第一个参数为构造函数
var Func = arguments[0];
// 将新对象的原型指向构造函数的原型链;
// prototype是一个拥有`constructor`内部方法的对象(函数)才有的属性(函数同时也有__proto__,只要是对象就有`__proto__`)。newFunc 不是一个函数,没有`constructor`,没有prototype,只有`__proto__`;
newFunc.__proto__ = Func.prototype;
// 将构造函数的this指向新对象;
var res = Func.apply(newFunc, args);
// 判断构造函数中是否返回了其他对象,如果有返回对象,则将构造函数的返回对象返回;否则返回新对象;
if (res && (typeof res === 'object' || typeof res === 'function')) {
return res;
}
return newFunc;
}
var test1 = _new(Test1, 'lalala');
var newTest1 = new Test1('lalala');
var test2 = _new(Test2, 'lalala');
var newTest2 = new Test2('lalala');
console.log('_new', test1);
console.log('new', newTest1);
console.log('_new', test2);
console.log('new', newTest2);
image.png
扩展:
prototype和proto分别是什么?
prototype(显式原型)是对象的一个属性(每个对象都有一个prototype属性),这个属性是一个指针,指向一个对象,通过它可以向对象添加属性和方法。
proto(隐式原型)是对象的一个内置属性,是JS内部使用寻找原型链的属性,也就是说,当我们访问obj这个对象中的x属性时,如果在obj中找不到,那么就会沿着proto依次向上查找。
网友评论