【问题标题】:why MDN argues that JS classes "may cause an error"?为什么 MDN 认为 JS 类“可能会导致错误”?
【发布时间】:2020-05-21 23:32:14
【问题描述】:

编辑 关于 Barmar 的请求,我上传了这个截图。正如 Jake 声称的那样,这是关于那个声明的。

在这篇文章中MDN 解释了一些关于 JS 继承的细节,包括解释为什么 JS 经典继承模型比 JS 类更安全。他们在本文中做了很多有用的事情,但我没有看到这一点得到体现。有人能指出 MDN 的论点,证明传统语法比类语法更安全吗?

谢谢

奖励:我完成了上述文章中实施的“员工示例”的简短版本。据此,传统语法并不安全,而是更长且难以遵循:

//TRADITIONAL SYNTAX

function Participant ({gender, tastes}){
  this.gender = gender;
  this.tastes = tastes || [];
}
function NotPayer({gender, tastes, role}){
  this.role = role || 'kid';
  this.base = Participant;
  this.job = 'Not Valid';
  this.base({gender, tastes});
}

NotPayer.prototype = Participant.prototype;

const kid1 = new NotPayer({role: 'nephew', gender: 'male', tastes: ['golf']});
console.log(kid1.gender); //male
const kid2 = new Participant({gender: 'female'});
console.log(kid2.gender); // female

//MODERN SYNTAX

class Participant {
    constructor({gender, tastes}){
        this.gender = gender;
        this.tastes = tastes || [];
      }
}
class NotPayer extends Participant {
    constructor({gender, tastes, role}){
        super({gender, tastes});
        this.role = role || 'kid';
      }
}
const kid1 = new NotPayer({role: 'nephew', gender: 'male', tastes: ['golf']});
console.log(kid1.gender);//male
const kid2 = new Participant({tastes: ['dance'], gender: 'female2'});
console.log(kid2.gender);// 'female2'

【问题讨论】:

  • 可能是因为所有浏览器还没有完全支持JS类的原因。例如,Internet Explorer 中不支持 class 语法。
  • 文章没有提到传统语法的安全性,你指的是the statement over the code snippet吗?我想他们确实掩盖了你为什么应该use this instead,但意图很明确。传统语法几乎可以在任何 javascript 引擎上运行,而“类”语法则不能。
  • 我不认为其目的是要说明可以在何处使用语法。就是“对于以下示例”,不要使用类语法。接下来是原型继承的示例,例如 ManagerWorkerBee 对象,它们不适用于类(必须使用 new 实例化)
  • @HereticMonkey 您应该将其发布为答案,这就是确切的原因。如果将class 与“以下示例”一起使用,那么var sally = new Manager 将抛出TypeError: class constructors must be invoked with 'new'
  • 关于像第二个 sn-p 一样运行代码有多安全?与其他任何东西一样安全,只要您在相对较新的浏览器中运行它,或者使用 Babel 或其他东西将其转换为旧浏览器可以理解的东西。老实说,这些天你必须担心的是 IE 和真正的旧 Apple 设备。

标签: javascript class inheritance ecmascript-6


【解决方案1】:

文章中的文字是其下方代码示例的标题。它说

JavaScript(使用它可能会导致以下示例出错)

然后继续展示一个类语法的例子。紧随该示例的是一个标题说

JavaScript **(改用这个)

后面是(构造函数)函数语法的示例。

然后它显示了 Java 如何处理类。然后本文稍微讨论了原型继承,这是 JavaScript 在引入类之前的面向对象设计的关键部分,并随后给出了该类型继承的示例。

正是在这些示例中,如果使用最初介绍的类语法示例,代码将失败。

只是为了搞笑,这里有一个 Stack Snippet 显示发生了什么:

class Employee {
  constructor() {
    this.name = '';
    this.dept = 'general';
  }
}

function Manager() {
  Employee.call(this);
  this.reports = [];
}
Manager.prototype = Object.create(Employee.prototype);
Manager.prototype.constructor = Manager;

console.log(new Manager());

当您在此处(在适当的现代浏览器上)单击运行代码 sn-p 时出现的错误 (Uncaught TypeError: Class constructor Employee cannot be invoked without 'new') 就是“使用它可能会导致错误”文本所说的内容。 “for the following examples”是短语的关键部分。

【讨论】:

    【解决方案2】:

    MDN 警告认为文章中开发的示例无法在某些引擎中运行,而不是暗示传统语法优于现代语法。正如AshishJake 所指出的,这与JS 引擎对类语法的支持有关。

    尽管如此,我认为 MDN 文章可能会更明确地说明这一点(因为该论证涉及许多复杂的主题。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-04
      • 2020-07-16
      • 2014-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多