方法说明javascript
new
运算符会建立一个用户自定义对象类型(就是自定义函数、或者说构造函数)的实例或具备构造函数的内置对象(好比:Number、String等原生对象)的实例,具体的过程以下:java
建立一个空对象,
{}
闭包
- 将第一步的空对象连接到另外一个对象(
new
操做符后面跟着的构造函数的原型对象)- 将第一步建立的对象做为构造函数的
this
上下文- 返回对象实例,若是构造函数有返回对象,则对象实例就是构造函数返回的对象,不然就返回
this
做为对象实例
划重点函数
从上面的第3步和第4步能够看出来,经过new
操做符建立一个对象实例时,构造函数中的this
并不必定指向建立出来实例对象,你们能够复制如下 “示例代码” 去测试:
示例代码测试
// 示例一,构造函数没有返回对象,this等于建立出来的实例对象 let obj1 = null function E1 () { obj1 = this } const ins1 = new E1() console.log(obj1 === ins1) // true // 示例二,构造函数返回了一个对象,this不等于建立出来的实例对象 let obj2 = null function E2 () { obj2 = this return { e: 'ee' } } const ins2 = new E2() console.log(obj2 === ins2) // false
源码点拨this
逻辑较为简单,重点在于理解上面的 “方法说明” 、 “划重点”、”示例代码“ 三部份内容,源码就是实现 “方法说明” 的一个过程,经过
闭包 + Object.create() + Function.prototype.call
来实现,具体的可参考代码中的详细注释
源码prototype
const myNew = function (constructor) { return function (...args) { // 完成一、2两步,建立一个连接到构造函数的原型对象的对象 const obj = Object.create(constructor.prototype) // 将obj做为构造函数的this上下文 constructor.call(obj, ...args) // 若是构造函数有返回值,则将返回值做为实例对象返回,不然返回obj做为实例对象 return constructor() || obj } } // 示例 1,构造函数无返回值 function T1 (arg1, arg2) { this.arg1 = arg1 this.arg2 = arg2 } const ins1 = myNew(T1)(1, 2) console.log(ins1) // {arg1: 1, arg2: 2} // 示例 2,构造函数有返回值 function T2 (arg1, arg2) { this.arg1 = arg1 this.arg2 = arg2 return { a: 'aa' } } const ins2 = myNew(T2)(1, 2) console.log(ins2) // {a: "aa"}