new 关键词的主要做用就是执行一个构造函数、返回一个实例对象,在 new 的过程当中,根据构造函数的状况,来肯定是否能够接受参数的传递。下面咱们经过一段代码来看一个简单的 new 的例子
new 操做符能够帮助咱们构建出一个实例,而且绑定上 this,内部执行步骤可大概分为如下几步:
若是不用 new 这个关键词,结合上面的代码改造一下,去掉 new,会发生什么样的变化呢?咱们再来看下面这段代码
// 'use strict'; function Person() { this.name = "江小白"; } var p = Person(); console.log(p); //undefined console.log(name) //江小白 console.log(p.name); // Cannot read property 'name' of undefined
function Person() { this.nem = "江小白"; return { age: 22 }; } var p = new Person(); console.log(p); //{ age: 22 } console.log(p.name); //undefined console.log(p.age); //22
经过这段代码又能够看出,当构造函数最后 return 出来的是一个和 this 无关的对象时,new 命令会直接返回这个新对象,而不是经过 new 执行步骤生成的 this 对象app
可是这里要求构造函数必须是返回一个对象,若是返回的不是对象,那么仍是会按照 new 的实现步骤,返回新生成的对象。接下来仍是在上面这段代码的基础之上稍微改动一下函数
function Person(){ this.name = '江小白'; return 'tom'; } var p = new Person(); console.log(p) // {name: '江小白'} console.log(p.name) // 江小白
💝 所以咱们总结一下:
new 关键词执行以后老是会返回一个对象,要么是实例对象,要么是 return 语句指定的对象
// 手写模拟new function myNew(fn, ...args) { if (typeof fn !== 'function') { throw 'fn mast be a function'; } // 1. 用new Object()建立一个对象obj var obj = new Object(); // 2. 给该对象的__proto__赋值为fn.prototype,即设置原型链 obj.__proto__ = Object.create(fn.prototype); // 3. 执行fn,并将obj做为内部this。使用 apply, // 改变构造函数 this 的指向到新建的对象, // 这样 obj 就能够访问到构造函数中的属性 var result = fn.apply(obj, args); // 4. 若是fn有返回值,则将其做为new操做返回,不然返回obj return result instanceof Object ? result : obj; }
// test function Person(...args) { console.log(args) } // 使用内置函数new var person1 = new Person(1,2) console.log(person1) // 使用手写的new,即create var person2 = myNew(Person, 1, 2) console.log(person2)
new 被调用后大体作了哪几件事情