:手写一个新的,需要理解prototype的概念,以及this的指向问题。执行new时我们做了什么让我们执行new看看在new过程中发生了什么:}}constperson=newPerson('ayetongzhi')console.log('person',person)person.sayName()打印结果如上,根据打印结果我们可以知道:返回了一个对象(人),this对象不是凭空创建的,所以在new的过程中创建并返回了一个对象。将其设置为指向创建的新对象,并执行函数。您需要将this指向新对象,以便将构造函数的属性分配给实例对象。更改实例的\_\_proto\_\_属性以指向构造函数的原型。如下图所示,构造函数(Function)创建的实例(instance),其\_\_proto\_\_属性指向构造函数(Function)的原型。显式返回对象的构造函数返回该对象。这里解释一下这个问题,上面的代码:functionPerson(name){this.name=name;this.sayName=function(){console.log("name",this.name);};//显示返回一个对象return{name:"maomao",sayName:function(){console.log("name",this.name);}};}constperson=newPerson("ayetongzhi");console.log("person",person);person.sayName();//maomao操作结果显示return后返回的对象是newPerson操作后返回的。根据新建操作的内容实现新建,逐步实现手写新建。//fn构造函数//...args传入的参数constructorfunctionmyNew(fn,...args){//创建一个新对象varobj={}//将对象的__proto__属性指向构造函数Prototypeobj.__proto__=fn.prototype//将**this**指向创建的新对象,执行构造函数,保存返回结果letresult=fn.call(obj,...args)//从构造函数返回如果结果是一个对象,返回对象result,否则返回新建对象objreturnresultinstanceofObject?result:obj}通过上面的代码,我们实现了手写new,但是\_\_proto\_\_属性是一个有争议的弃用属性,我们改用Object.create()方法。Object.create()方法用于创建新对象,使用现有对象作为新创建对象的原型。例如:leta={name:'maomao'}letb=Object.create(a)console.log('b's__proto__pointstoa',b.__proto__===a)//上面的代码为真letb=Object.create(a)使新创建的对象b的\_\_proto\_\_指向已有的对象a。因此,我们来优化一下手写的myNew方法://fnconstructor//...args构造函数传入的参数myNew(fn,...args){//创建一个新对象obj,并改变obj的__proto__指向构造函数的原型varobj=Object.create(myNew.prototype)//指向**this**创建的新对象,执行构造函数,保存返回结果letresult=fn.call(obj,...args)//如果构造函数返回的结果是对象,则返回对象result,否则返回新创建的对象objreturnresultinstanceofObject?result:obj}运行如下代码,检查手写的new方法是否有问题:functionPerson(name){this.name=name;this.sayName=function(){console.log("name",this.name);};}constperson=myNew(Person,"ayetongzhi");console.log("person",person);person.sayName();//ayetongzhi在没有显示的返回对象时创建一个新的对象。并且把this改成指向新对象,同时执行构造函数。将新建对象的\_\_proto\_\_改为指向构造函数的原型,与new操作符的执行结果一致。.函数Person(name){this.name=name;this.sayName=function(){console.log("name",this.name);};return{name:"maomao",sayName:function(){console.log("name",this.name);}};}constperson=myNew(Person,"ayetongzhi");console.log("person",person);person.sayName();//maomao在构造函数返回对象时,打印结果如下,与new操作符的执行结果一致。以上我们了解了new操作执行时做了什么,根据new操作的表现,我们实现了手写new功能。
