一、什么是new?
众所周知,在JS中,new的作用是通过构造函数来创建一个实例对象。
像下面这样:(和普通函数不一样,当函数用作 构造函数 时,首字母一般要大写,以作区分。)
function Foo(name) { this.name = name;}console.log("new Foo('mm')的类型:",typeof new Foo('mm')); // objectconsole.log("Foo的类型:",typeof Foo); // function
二、new经历了什么过程?
Foo明明只是一个函数,可是为什么new Foo()执行后会突然返回一个对象呢?
我们从结果出发可以推断出,既然返回了一个对象,那么这事肯定和 对象 有关系。
实际上new帮我们做了这样几件事:
- 帮我们创建了一个空对象,例如:obj;
- 将空对象原型的内存地址 __proto__ 指向函数的原型对象;(这里涉及到了 原型链 的知识)
- 利用函数的call方法,将原本指向window的绑定对象this指向了obj。(这样一来,当我们向函数中再传递实参时,对象的属性就会被挂载到obj上。)
- 利用函数返回对象obj。
三、new的过程分析
function Foo(name) { this.name = name; return this;}var obj = {};obj.__proto__ = Foo.prototype;// Foo.call(obj, 'mm');var foo = Foo.call(obj, 'mm');console.log(foo);
分析:
首先预编译,声明提升,解释执行。
执行时按照顺序来进行,
- obj指向空对象;
- obj的原型地址指向构造函数Foo的原型对象;
- 执行 Foo.call(obj, 'mm');this.name = name; 通过函数的 call方法 将this绑定到obj(也就是说this就是obj),实参mm传入构造函数Foo中,这样this.name = ‘mm’,那么obj.name = ‘mm’,也就是说name属性被挂载到obj对象上。return this; 就是return obj,这样obj这个对象就被返回出来了。
- 将结果赋值给变量foo。
- 打印结果。
四、总结
第三部分的代码直接用 new 构造函数 效果是相同的。
function Foo(name) { this.name = name;}var foo = new Foo('mm');console.log(foo);
简而言之,new操作符帮我们做了四件事:
- 创建空对象;
- 空对象的原型指针指向构造函数的原型对象;
- 利用函数的call方法改变this指向,在空对象上挂载属性或方法;
- 返回对象。