首页 > 解决方案 > 基于原型的构造函数和 ES6 类的区别

问题描述

我试图了解以下 3 个功能之间的区别。经过一天的 MDN 和其他来源,我得出了一些“结论”,我想知道是否有人可以帮助我验证它们。谢谢 :)

BLOCK #1(基于原型的构造函数示例)

function Person (name){
    this.name = name;
    this.greeting = function(){
      alert(this.name);
      };
    }
  var person = new Person('Bob');

BLOCK #2(另一个基于原型的构造函数示例)

function Person(name) {
      this.name = name;
    }
    Person.prototype.greeting = function() {
      alert(this.name);
    }
  let person = new Person("Bob");

BLOCK #3(基于原型的 ES6 类示例)

 class Person {
   constructor(name) {
     this.name = name;
   }
   greeting() {
     alert(this.name);
   }
 }
 let person = new Person("Bob");

问题:

  1. 这三个函数将 name 和 greeting 成员添加到 Person 对象原型中。这个说法正确吗?

  2. Block #3 中的代码使用新的 ES6 类关键字,并以与 Block #1 和 Block #2 中的代码不同的方式在“幕后”工作。(PS。我正在写“幕后”,因为我还没有清楚地了解当我调用该函数时引擎盖下会发生什么,但目前我认为我太陌生了,无法深入研究)。

  3. Block #1 和 Block #2 中的代码达到相同的效果,并以相同的方式在“幕后”工作。两者代码的区别在于,在 Block #1 中,我们将name变量和函数保存greeting在同一个代码块中,而在 Block #2 中,我们将函数greeting与变量分开name(将greeting函数添加到 Person 原型, 使用Person.prototype.greeting)

  4. 在 Block #2 中使用,我们获得了与在 Block #1中放入以下Person.prototype.greeting = function () {...}相同的结果this.greeting = function (...)this.name

谢谢!

标签: javascriptclassecmascript-6prototype

解决方案


要回答问题:

  1. 不,该语句不正确,代码都没有将“名称”添加到原型中,只有代码块 #2 和 #3 将问候语添加到原型中。
  2. 可能潜水太深了,我无法验证幕后究竟发生了什么,但代码本质上表现为块#2。
  3. 代码块 #1 和 #2 肯定不会以相同的方式工作,也不会达到相同的最终结果。第一个块(我必须提醒你,正如我所写,因为我假设你在复制粘贴中犯了错误)将创建一个对象的实例并将属性名称和函数问候分配给新创建的实例,而代码块 #2 将属性名称分配给实例,但函数问候原型,所以你的问题 #3 的另一半是正确的。
  4. 绝对不是,对于使用块 #1 创建的每个对象,您都在定义和创建函数greeting的新实例并将其附加到新创建的对象,在这种情况下您根本没有使用原型继承。

推荐阅读