在实现new方法之前我们需要了解js自带的new都有哪些作用,以及实现了哪些功能,这样以便于我们去实现它
首先,我们都知道new的作用是将构造函数实例化出来一个对象,那如果不使用new操作符,函数是如何实例化的呢
//我们要先创建一个构造函数
function Person(name,age) {
this.name = name;
this.age = age;
}
//然后我们在构造函数的原型上构造一个方法
Person.prototype.sayName = function() {
console.log(this.name);
}
//接下来我们直接调用构造函数来看看结果如何
var person = Person('rose',20);
console.log(person);//结果是undefined
console.log(window.name);//'rose'
接下来我们再看使用new运算符的代码执行
function Person(name,age) {
this.name = name;
this.age = age;
}
//接下来同样在原型上定义一个方法
Person.prototype.sayName = function() {
console.log(this.name);
}
var person = new Person('roes',20);
console.log(person);//Person {name: 'rose', age: 20}
person.sayName();//rose
我们经过使用new操作符和没使用new操作符两段代码的对比,我们可以得出new的作用
- 调用了当前的构造函数
- 在内存当中创建了一个空对象
- 而且将构造函数的prototype值赋值给了新对象的__proto__
- 构造函数的内部this指向了新对象
- 执行构造函数内部的代码,也就是给新对象添加属性
- 如果构造函数传入的参数当中有对象,那么就输出这个对象的值,反之输出我们刚才创建的新对象
接下来我们来看代码
//第一步我们先创建一个mynew方法
function mynew() {
//接下来我们创建一个空对象用来接收构造函数当中的属性
var obj = new Object();
//这一步也就是帮助我们拿到传入参数中的第一个参数,也就是我们的构造函数constructor,
//所以在一会我们使用mynew方法的时候第一个参数要传的也就是我们的构造函数
var constructor = [].shift.call(arguments);
//我们把构造函数的原型赋给新对象,给新对象添加原型属性等等
obj.__proto__ = constructor.prototype;
//这一步用来设置一个新的返回值,来判断我们返回值的类型是什么
var returned = constructor.apply(obj,arguments);
//如果我们构造函数传入的参数是一个对象形式的,那么就返回这个对象,反之返回新对象
return typeof(returned) == "object" ? returned : obj;
}
//让我们来实验一下
Person.prototype.money = "more";
function Person(name,age) {
this.name = name;
this.age = age;
}
var person = mynew (Person,'rose',20);
console.log(person);//{name: 'rose', age: 20}
console.log(person.__proto__);//{money: 'more', constructor: ƒ}
如此可以看出我们写的代码没有问题,我们成功实现了new关键字