如下是 MDN 对 new 运算符的描述:
先按照 MDN 的描述一步一步来
自定义的方法格式 myNew(constructor,[arguments1],[arguments2]...)
/*
定义一个 myNew 方法 模拟对象的 new 关键字的功能
参数:
Cons 构造函数,
...args 接受剩余参数
*/
function myNew(Cons,...args){
// 1.创建一个空对象
const obj = {};
// 2.为这个对象指定隐式原型属性(实例对象是没有 prototype 的)
obj.__proto__ = Cons.prototype;
// 3.调用构造器(使用 apply 改变里面的 this 指向 obj 并把参数传递过去)
Cons.constructor.apply(obj,args);
// 4.返回obj
return obj;
}
测试代码:
function myNew(Cons,...args){
// 1.创建一个空对象
const obj = {};
// 2.为这个对象指定隐式原型属性(实例对象是没有 prototype 的)
obj.__proto__ = Cons.prototype;
// 3.调用构造器(使用 apply 改变里面的 this 指向 obj 并把参数传递过去)
Cons.constructor.apply(obj,args);
// 4.返回obj
return obj;
}
// Person 构造函数
function Person(name,age){
this.name = name;
this.age = age;
}
const p1 = new Person('张三',18); // 使用 new
const p2 = myNew(Person, '李四', 28); // 使用 自定义方法
console.log('我是p1',p1);
console.log('我是p2',p2);
console.log(p1.__proto__ === p2.__proto__); // 实例原型比较
console.log(p2.__proto__ === Person.prototype); // 实例与构造函数的原型对象比较
控制台输出结果:
可以修改一下 myNew
让代码简洁一点
function myNew(Cons) {
// Object.create 方法会返回一个 新对象,带着指定的原型对象和属性(MDN定义)
const obj = Object.create(Cons.prototype);
obj.info = '使用了 Object.create'; // 这个属性就是标识一下的, 没有其他意思
// 可以只接受构造函数 其他参数使用 arguments 代替也是可以的(当然全用arguments也可以就是不美观)
Cons.apply(obj, arguments);
return obj;
}
同样输出: