前端百题斩——从验证点到手撕New操作符

18.1 基础

new的作用是通过构造函数来创建一个实例对象,该实例与原型和构造函数之间的关系如下图所示:

创新互联公司成立以来不断整合自身及行业资源、不断突破观念以使企业策略得到完善和成熟,建立了一套“以技术为基点,以客户需求中心、市场为导向”的快速反应体系。对公司的主营项目,如中高端企业网站企划 / 设计、行业 / 企业门户设计推广、行业门户平台运营、重庆APP软件开发成都做手机网站、微信网站制作、软件开发、西部信息服务器租用等实行标准化操作,让客户可以直观的预知到从创新互联公司可以获得的服务效果。

18.2 new过程中发生了什么

当一个构造函数new的过程到底发生了什么?简要概述主要分为以下几个步骤:

  • 一个新对象被创建;
  • 该对象的__ proto __属性指向该构造函数的原型,即Fn.prototype;
  • 将执行上下文(this)绑定到新创建的对象中;
  • 如果构造函数有返回值(对象或函数),那么这个返回值将取代第一步中新创建的对象。

new真的做了这几步吗?秉承着“实践是检验真理的唯一标准”的原则,下面将这几个关键点进行逐一验证。

 
 
 
 
  1. function Fun() { 
  2.     this.a = 10; 
  3.     this.b = 20; 
  4.     this.method1 = () => { 
  5.         return this.a + this.b; 
  6.     } 
  7.     this.method2 = () => { 
  8.         return this; 
  9.     } 
  10.  
  11. Fun.prototype = { 
  12.     method2: () => { 
  13.         console.log('原型上的method1被访问'); 
  14.     } 

18.2.1 验证点1——新对象被创建

验证点1是新对象被创建,其实这个里面有两层含义:

new之后返回的内容是一个对象

 
 
 
 
  1. const fun = new Fun(); 
  2. console.log(fun); //  { a: 10, b: 20, method1: [Function] } 
  3. console.log(typeof(fun)); // object 

通过打印其内容,并通过typeof进行验证,其返回内容确实是一个对象。

每次返回的都是一个新创建的对象

 
 
 
 
  1. const fun1 = new Fun(); 
  2. const fun2 = new Fun(); 
  3. console.log(fun1 === fun2); // false 

通过创建两个实例,通过判断两个实例不相等,则证明确实每次返回的是一个新的对象。

18.2.2 验证点2——该对象可访问原型上的属性和方法

验证点2是新创建的实例可访问原型上的属性和方法,验证该关键点只需要访问原型上的方法即可实现,若原型上的方法能够被正常访问,则表示该验证点通过,负责不通过。

 
 
 
 
  1. const fun3 = new Fun(); 
  2. fun3.method3(); // 原型上的method3被访问 

通过验证,原型上的方法确实能够被访问。

18.2.3 验证点3——this指向

验证this指向只需要将this指向打印出来即可。

 
 
 
 
  1. const fun4 = new Fun(); 
  2. console.log(fun4.method2()); // { a: 10, b: 20, method1: [Function], method2: [Function] } 
  3. console.log(fun4.method2() === fun4); // true 

18.2.4 验证点4——构造函数有返回值的处理逻辑

一个函数的返回值可以有多种,例如:string、boolean、number、Object、function等,下面我们验证一些内容,看构造函数有不同的返回值,其实例为何值。

返回值为string

 
 
 
 
  1. function Fun() { 
  2.     this.a = 10; 
  3.     this.b = 20; 
  4.     return 'test'; 
  5. Fun.prototype = { 
  6.     method: () => { 
  7.         console.log('原型上的method被访问'); 
  8.     } 
  9.  
  10. const fun = new Fun(); 
  11. console.log(fun); // { a: 10, b: 20 } 

观察其最终结果,字符串没有没正常返回,返回值是一个新的实例。

返回值为Object

 
 
 
 
  1. function Fun() { 
  2.     this.a = 10; 
  3.     this.b = 20; 
  4.     return { 
  5.         c: 30 
  6.     }; 
  7. Fun.prototype = { 
  8.     method: () => { 
  9.         console.log('原型上的method被访问'); 
  10.     } 
  11.  
  12. const fun = new Fun(); 
  13. console.log(fun); // { c: 30 } 

观察其结果,返回值是函数中返回的对象,则表征当构造函数返回值为对象时,会返回其对象,不返回实例化后的内容。

返回值为function

 
 
 
 
  1. function Fun() { 
  2.     this.a = 10; 
  3.     this.b = 20; 
  4.     return function() { 
  5.         this.d = 40; 
  6.     }; 
  7. Fun.prototype = { 
  8.     method: () => { 
  9.         console.log('原型上的method被访问'); 
  10.     } 
  11.  
  12. const fun = new Fun(); 
  13. console.log(fun); // [Function] 

返回函数的效果和返回对象的效果一致。

通过不断尝试总结,可以得出以下结论:

构造函数的返回值为基本类型,其返回值是实例化后的对象,不受返回值的影响;

构造函数的返回值是引用类型,其返回值即为new之后的返回值。

18.3 实现一个new

介绍了这么多,已经理解了new时发生的事情并经过了验证,下面就手动实现一个自己的new函数。

 
 
 
 
  1. function myNew(Fn, ...args) { 
  2.     // 一个新的对象被创建 
  3.     const result = {}; 
  4.     // 该对象的__proto__属性指向该构造函数的原型 
  5.     if (Fn.prototype !== null) { 
  6.         Object.setPrototypeOf(result, Fn.prototype); 
  7.     } 
  8.  
  9.     // 将执行上下文(this)绑定到新创建的对象中 
  10.     const returnResult = Fn.apply(result, args); 
  11.     // 如果构造函数有返回值(对象或函数),那么这个返回值将取代第一步中新创建的对象。 
  12.     if ((typeof returnResult === 'object' || typeof returnResult === 'function') && returnResult !== null) { 
  13.         return returnResult; 
  14.     } 
  15.     return result; 

小试牛刀

 
 
 
 
  1. function Fun() { 
  2.     this.a = 10; 
  3.     this.b = 20; 
  4. Fun.prototype = { 
  5.     method: () => { 
  6.         console.log('原型上的method被访问'); 
  7.     } 
  8. const fun1 = new Fun(); 
  9. console.log(fun1); // { a: 10, b: 20 } 
  10. const fun2 = myNew(Fun); 
  11. console.log(fun2); // { a: 10, b: 20 } 

网站名称:前端百题斩——从验证点到手撕New操作符
文章链接:http://www.36103.cn/qtweb/news39/589.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联