new做了什么
先看一下mdn的解释吧
- 创建一个空的简单 JavaScript 对象(即
{});- 为步骤 1 新创建的对象添加属性
__proto__,将该属性链接至构造函数的原型对象;- 将步骤 1 新创建的对象作为
this的上下文;- 如果该函数没有返回对象,则返回
this。
感觉还算好理解,毕竟学过new对象时this指向的就是新创建的对象,原型链又是一层一层往上的。
既然这样,我们来模拟一下new吧
思路:写一个函数来模拟new,传入的第一个参数是构造函数,之后的参数是原本new时传入的参数
// 第一版代码
function objectFactory() {
var obj = {}, //这里用var obj = {}也是一样的
//Constructor = [].shift.call(arguments); //讶羽大佬的代码
Constructor = arguments[0]; //第一个参数是构造函数
obj.__proto__ = Constructor.prototype; //传承作用域链
//Constructor.apply(obj, arguments); //讶羽
Constructor.apply(obj, Array.from(arguments).slice(1)); //改变指向
return obj;
};
Constructor = [].shift.call(arguments);
这操作对于我来说真是有点难以理解了,arguments不是数组,又需要把arguments的第一项抽出来,不然apply的时候会多出来一个参数。这一步就完成了。。
实验一下
function FatOtaku (name, age) {
this.name = name;
this.age = age;
this.habit = 'Games';
}
FatOtaku.prototype.strength = 60;
FatOtaku.prototype.sayYourName = function () {
console.log('I am ' + this.name);
}
function objectFactory() {
var obj = new Object(),
Constructor = arguments[0];
obj.__proto__ = Constructor.prototype;
Constructor.apply(obj, Array.from(arguments).slice(1));
return obj;
};
var person = objectFactory(FatOtaku, 'Kevin', '18')
var person1 = new FatOtaku('Kevin1', '28')
console.log(person.name) // Kevin
console.log(person1.name) // Kevin1
console.log(person.age) // 18
console.log(person1.age) // 28
console.log(person.habit) // Games
console.log(person1.habit) // Games
console.log(person.strength) // 60
console.log(person1.strength) // 60
person.sayYourName(); // I am Kevin
person1.sayYourName(); // I am Kevin1