1. new操作中发生了啥?
在《javaScript模式》中,对于new的过程是这样描述:
- 创建一个空对象,将它的引用赋给this,继承函数的原型
- 通过this将属性和方法添加至这个对象
- 最后返回this指向的新对象,也就是实例 通过书中说明,代码大概是这样:
let Parent = function (name, age) {
// 1. 创建一个新对象,赋予this,这一步是隐形的
// let this = {};
// 2. 给this指向的对象赋予构造属性
this.name = name;
this.age = age;
// 3. 如果没有手动返回对象,则默认返回this指向的这个对象,也是隐形的
// return this;
}
工作中大家应该看过类似下面的代码,将this赋予一个新的变量,例如that,最后返回这个变量:
// ES5构造函数
function Parent (name, age) {
let that = this;
that.name = name;
that.age = age;
return that;
};
const child = new Parent('诺安人', 24); // {name = '诺安人', age: 24}
因为this的创建是隐形的,但在工作中为了让构造过程更易可见和维护,所有采用that代替this,最后手动返回that,这也验证了隐形的两个步骤的确存在。
2. 下面实现一个简单的new方法:
function create() {
// 创建一个空的对象
let obj = new Object()
// 将arguments转换成数组,再调用shift方法返回第一个参数,也就是构造函数
let Con = [].shift.call(arguments)
// 链接到原型
obj.__proto__ = Con.prototype
// 绑定this,执行构造函数(因为apply会自动执行函数,注意现在的argument里面只有传递进来的属性值)
let result = Con.apply(obj, arguments)
// 这里进行判断,如果构造函数最后有return操作,那就返回构造函数里面那个对象,没有则返回obj
// 其实就是对应我们上面所说的那个隐形返回
return typeof result === 'object' ? result : obj
}
function Person (name, age) {
this.name = name
this.age = age
return this
}
let a = create(Person, '诺安人', 24) // {name = '诺安人', age = 24}
刚开始我不理解 return typeof result === 'object' ? result : obj 这句代码的含义,直到明白了原来有两步隐形操作,后来才恍然大悟。
希望能帮到同样有困惑的童鞋们!