new
的使用场景:一般是用来创建一个 obj 实例的。
代码分析:
function People(name) { // 构造函数可以直接以函数的方式来使用
this.name = name;
console.log(this);
return {name: name};
}
var p1 = new People("zlq");
var p2 = People("zs");
console.log(p1);
console.log(p2);
结果如下:
结论:
- new之后,this指向是一个People实例对象,正真的实例化了对象
- 以函数的方式调用的时候,this指向是window对象
new 实例过程分析:
- 创建一个新的空对象
- 让新对象的
__proto__
成员对象指向构造函数的prototype
成员对象 – 实则产生的是一个新的上下文 - 使用 call 或 apply 调用构造函数,为新对象添加属性、方法
- 判断第 3 步中的值,如果构造函数没有返回其他对象,那么返回this,即新的对象,否则返回构造函数中返回的对象
// 代码解析
new people() = {
let obj = {};
let [constructor, ...args] = [...arguments]; // 第一个参数是 构造函数
obj.__proto__ = constructor.prototype;
let res = constructor.apply(obj, args);
return typeof res === 'object' ? res : obj;
}
此番操作后新对象的原型链:
obj.__proto__
==> People.prototype ==> Object.prototype ==> null;
obj 继承了 People 原型上的属性、方法,即实现了继承。
结论:
new 操作符,可以创建一个原型对象的实例对象,并且继承了原型对象的属性、方法,故new不仅仅是实例化一个对象,同时也实现了 js 的继承。 可与 es6 中的 class 继承作对比,this的指向获取方式不同。
温馨提示: 文章参考部分博客及个人理解,如有错误,请大家及时指正。