作用:创建一个构造函数的实例对象。
知识储备
- 实例.proto = 类.prototype
- apply修改this指向,同时传入参数。即把我的某个方法借用给别的对象使用,同时把参数丢入
- 实参里第一个参数:就是构造函数
从arguments类数组中提取出,构造函数和传入的 参数
也就是分别提取 第一个、第二个元素
fn
[].slice.call(arguments)[0]//数组的slice方法会把伪数组转成数组
或
[]shift.call(arguments)//shift:把数组的第一个元素删除并返回该元素
或
[...arguments][0]//...是es6 的扩展运算符,把伪数组浅拷贝到空数组[]里
params
[].slice.call(arguments)[1]
- ps:slice 或是shift方法会将具有length属性的对象(伪数组) 转换成数组
- 伪数组:{ 0:'Macrolam', 1:'女', length:2}
实现步骤
1. 在内存中创建一个新对象
2. 获取构造函数,实参arguments伪数组里第一个
3. 连接原型,新对象可以访问原型中的属性,实例.proto = 类.prototype
4. 把构造函数当普通函数进行执行,把构造函数的this指向新对象,并且为这个新对象添加属性
5.分析函数返回值,如果构造函数本身有返回值,优先,否则,返回新对象。
代码实现
function _new(){
let obj = new Object()
let constructor = [].shift.call(arguments)
obj.__proro__ = constructor.prototype
let result = constructor.apply(obj,arguments)
return typeof result === 'object' ? result : obj
}
简单写法
function _new(fn) {
const obj = Object.create(fn.prototype);
result = fn.apply(obj, [...arguments].slice(1));
return typeof result === "object" ? result : obj;
}
var obj = Object.create(fn.prototype) 等价于:
var obj = new Object ();obj._proto_ = constructor.prototype;
测试代码
_new(Object,{name:'mac',age:22})//{name: 'mac', age: 22}