当前位置: 首页 > 科技观察

前端100题——从验证点到撕裂New操作符

时间:2023-03-16 22:18:27 科技观察

18.1基本new的作用是通过构造函数创建一个实例对象。实例、原型和构造函数的关系如下图所示:18.2new过程中发生了什么构造函数new的过程中到底发生了什么?简要概述分为以下步骤:创建一个新对象;对象的__proto__属性指向构造函数的原型,即Fn.prototype;将执行上下文(this)绑定到新创建的对象上;如果构造函数有一个返回值(对象或函数),那么这个返回值将替换第一步中新创建的对象。new真的做了这些步骤吗?本着“实践是检验真理的唯一标准”的原则,将对以下要点一一进行验证。functionFun(){this.a=10;this.b=20;this.method1=()=>{returnthis.a+this.b;}this.method2=()=>{returnthis;}}Fun.prototype={method2:()=>{console.log('访问原型上的method1');}}18.2.1验证点1——创建新对象验证点1是创建了一个新对象,实际上,有两层意思:new之后返回的内容是一个对象constfun=newFun();console.log(fun);//{a:10,b:20,method1:[Function]}console.log(typeof(fun));//对象打印它的内容,通过typeof验证返回的内容确实是一个东西。每次返回都是新创建的对象constfun1=newFun();constfun2=newFun();console.log(fun1===fun2);//false通过创建两个实例,通过判断两个实例不相等,证明每次确实返回一个新对象。18.2.2验证点2——对象可以访问原型上的属性和方法。验证点2是新创建的实例可以访问原型上的属性和方法。要验证这个关键点,只需要访问原型上的方法即可。如果原型上的方法可以正常访问,说明验证点通过,责任未通过。constfun3=newFun();fun3.method3();//访问并验证了原型上的method3,确实可以访问到原型上的方法。18.2.3验证点3——thispoint要验证这一点,只需要打印出这一点即可。constfun4=newFun();console.log(fun4.method2());//{a:10,b:20,method1:[函数],method2:[函数]}console.log(fun4.method2()===fun4);//true18.2.4验证点4——构造函数有返回值处理逻辑一个函数可以有多个返回值,例如:string,boolean,number,Object,function等,我们来验证一些内容,看构造函数有不同返回值,以及它的实例的值是多少。返回值为stringfunctionFun(){this.a=10;this.b=20;return'test';}Fun.prototype={method:()=>{console.log('访问了原型上的方法');}}constfun=newFun();console.log(fun);//{a:10,b:20}观察最后的结果,字符串没有正常返回,返回值是一个新的实例。返回值为ObjectfunctionFun(){this.a=10;this.b=20;return{c:30};}Fun.prototype={method:()=>{console.log('原型上的方法被访问');}}constfun=newFun();console.log(fun);//{c:30}观察结果,返回值是函数中返回的对象,也就是说当返回值构造函数是一个对象,它会返回它的对象,而不是实例化的内容。返回值为functionfunctionFun(){this.a=10;this.b=20;returnfunction(){this.d=40;};}Fun.prototype={method:()=>{console.log('prototype访问上面的方法');}}constfun=newFun();console.log(fun);//【功能】返回函数的效果和返回对象的效果是一致的。通过不断尝试总结,可以得出以下结论:构造函数的返回值是基本类型,其返回值是实例化对象,不受返回值影响;构造函数的返回值是引用类型,它的返回值是new之后的返回值。18.3实现一个new介绍了这么多,了解并验证了new会发生什么,下面我们手动实现一个自己的new函数。functionmyNew(Fn,...args){//创建一个新对象constresult={};//对象的__proto__属性指向构造函数的原型if(Fn.prototype!==null){Object.setPrototypeOf(result,Fn.prototype);}//给新创建的对象绑定执行上下文(this)constreturnResult=Fn.apply(result,args);//如果构造函数有返回值(对象或函数),然后这个返回值将替换第一步中新创建的对象。if((typeofreturnResult==='object'||typeofreturnResult==='function')&&returnResult!==null){returnreturnResult;}returnresult;}小测试函数Fun(){this.a=10;this.b=20;}Fun.prototype={method:()=>{console.log('原型上的方法被访问');}}constfun1=newFun();console.log(fun1);//{a:10,b:20}constfun2=myNew(Fun);console.log(fun2);//{a:10,b:20}