new运算符的模拟实现

82 阅读2分钟

js中new运算符作用?

new运算符创建了一个(用户自定义对象类型/内置对象类型)的实例,该实例具有一个constructor函数

new在创建实例的时候都做了哪些事

function Student(stuid, name) {
        this.stuid = stuid;
        this.name = name;
}

Student.prototype.sayName = function() {
        console.log(this.name);
};

let student = new Student('20150207', 'zorana');

console.log(student.stuid); // 20150207
console.log(student.name); // zorana
student.sayName(); // zorana

从上面可以看出 new做了下面这些事情

  1. 创建了一个新的对象实例,var obj = new Object
  2. 这个对象的隐式原型指向它的构造函数的原型 obj.proto = Student.prototype
  3. 执行构造函数,使其this指向这个对象。Student.apply(obj, [stuid, name]);
  4. 返回这个obj

下面我们模拟实现下new

//模拟实现new
function myNew(constructor, ...args) {
	const obj = new Object();
	obj.__proto__ = constructor.prototype;
	constructor.apply(obj, [...args]);
	return obj;
}
// 测试
function Student(stuid, name) {
	this.stuid = stuid;
	this.name = name;
}

Student.prototype.sayName = function() {
	console.log(this.name);
};

let student = myNew(Student, '20150207', 'zorana');

console.log(student.stuid); // 20150207
console.log(student.name); // zorana
student.sayName(); // zorana

从上面可以看出我们自己实现的new完成了上面四个事情。

但是上面的这种只覆盖了构造函数没有返回值的情形。 我们知道构造函数有return返回值的时候,如果return的是基本类型,则忽略return的值,会把新生成的对象返回。如果return的值是引用类型,则返回return后面跟着的对象。

下面我们继续完善myNew

// 模拟实现new
function myNew(constructor, ...args) {
	const obj = new Object();
	obj.__proto__ = constructor.prototype;
	const result = constructor.apply(obj, [...args]);
	return (typeof result === 'object')? result : obj;
}
// 测试代码
function Student(stuid, name) {
	this.stuid = stuid;
	this.name = name;
	return {stuid: '0001', name: 'zorana2'};
}

Student.prototype.sayName = function() {
	console.log(this.name);
};

let student = myNew(Student, '20150207', 'zorana');

console.log(student.stuid);  // 0001
console.log(student.name);  // zorana2
student.sayName();  // TypeError: student.sayName is not a function

上面因为构造函数本身是有return值的,并且是一个对象类型,所以new的时候最终返回的是构造函数本身返回的对象。