TLDR; ไม่จำเป็นอย่างยิ่ง แต่อาจจะช่วยได้ในระยะยาวและแม่นยำยิ่งขึ้น
หมายเหตุ: แก้ไขมากเป็นคำตอบก่อนหน้าของฉันถูกเขียนสับสนและมีข้อผิดพลาดบางอย่างที่ฉันพลาดในการเร่งรีบของฉันที่จะตอบ ขอบคุณผู้ที่ชี้ให้เห็นข้อผิดพลาดอย่างมหันต์
โดยพื้นฐานแล้วการวางสายย่อยให้ถูกต้องใน Javascript เมื่อเรา subclass เราต้องทำสิ่งที่ขี้ขลาดเพื่อให้แน่ใจว่าการมอบหมายต้นแบบทำงานอย่างถูกต้องรวมถึงการเขียนทับprototypeวัตถุ การเขียนทับprototypeวัตถุรวมถึงconstructorดังนั้นเราจึงจำเป็นต้องแก้ไขการอ้างอิง
เรามาดูกันว่า 'คลาส' ใน ES5 ทำงานอย่างไร
สมมติว่าคุณมีฟังก์ชั่นการสร้างและต้นแบบของมัน:
//Constructor Function
var Person = function(name, age) {
  this.name = name;
  this.age = age;
}
//Prototype Object - shared between all instances of Person
Person.prototype = {
  species: 'human',
}
เมื่อคุณเรียกนวกรรมิกเพื่อสร้างอินสแตนซ์ให้พูดว่าAdam:
// instantiate using the 'new' keyword
var adam = new Person('Adam', 19);
newคำหลักเรียกด้วย 'คน' โดยทั่วไปจะเรียกใช้ตัวสร้างคนที่มีบรรทัดเพิ่มเติมไม่กี่รหัส:
function Person (name, age) {
  // This additional line is automatically added by the keyword 'new'
  // it sets up the relationship between the instance and the prototype object
  // So that the instance will delegate to the Prototype object
  this = Object.create(Person.prototype);
  this.name = name;
  this.age = age;
  return this;
}
/* So 'adam' will be an object that looks like this:
 * {
 *   name: 'Adam',
 *   age: 19
 * }
 */
ถ้าเราconsole.log(adam.species)การค้นหาจะล้มเหลวที่adamอินสแตนซ์และมองขึ้นห่วงโซ่ prototypal ของมัน.prototypeซึ่งเป็นPerson.prototype- และPerson.prototype มีคุณสมบัติเพื่อให้การค้นหาจะประสบความสำเร็จใน.species Person.prototypeจากนั้นจะเข้าสู่ระบบ'human'จากนั้นจะเข้าสู่ระบบ
ที่นี่ได้อย่างถูกต้องจะชี้ไปที่Person.prototype.constructorPerson
ดังนั้นตอนนี้ส่วนที่น่าสนใจที่เรียกว่า 'subclassing' หากเราต้องการสร้างStudentชั้นเรียนซึ่งเป็นคลาสย่อยของPersonชั้นเรียนที่มีการเปลี่ยนแปลงเพิ่มเติมบางอย่างเราจะต้องตรวจสอบให้แน่ใจว่าStudent.prototype.constructorคะแนนของนักเรียนนั้นถูกต้อง
มันไม่ได้ทำด้วยตัวเอง เมื่อคุณคลาสย่อยโค้ดจะมีลักษณะดังนี้:
var Student = function(name, age, school) {
 // Calls the 'super' class, as every student is an instance of a Person
 Person.call(this, name, age);
 // This is what makes the Student instances different
 this.school = school
}
var eve = new Student('Eve', 20, 'UCSF');
console.log(Student.prototype); // this will be an empty object: {}
การเรียกnew Student()ที่นี่จะส่งคืนวัตถุที่มีคุณสมบัติทั้งหมดที่เราต้องการ นี่ถ้าเราตรวจสอบก็จะกลับมาeve instanceof Person falseหากเราพยายามเข้าถึงeve.speciesมันจะกลับมาundefinedมันจะกลับมา
ในคำอื่น ๆ ที่เราจำเป็นต้องลวดขึ้นคณะผู้แทนเพื่อให้eve instanceof Personผลตอบแทนที่แท้จริงและเพื่อให้กรณีของStudentผู้รับมอบสิทธิ์อย่างถูกต้องแล้วStudent.prototypePerson.prototype
แต่เนื่องจากเราเรียกมันด้วยnewคำหลักโปรดจำไว้ว่าการเรียกนั้นเพิ่มอะไร มันจะเรียกObject.create(Student.prototype)ซึ่งเป็นวิธีการที่เราตั้งค่าความสัมพันธ์ระหว่าง delegational และStudent Student.prototypeโปรดทราบว่าตอนนี้Student.prototypeว่างเปล่า ดังนั้นการค้นหา.speciesอินสแตนซ์ของStudentจะล้มเหลวเนื่องจากมอบหมายให้เท่านั้น Student.prototypeและ.speciesไม่มีคุณสมบัติอยู่Student.prototypeคุณสมบัติที่ไม่ได้อยู่ใน
เมื่อเราทำกำหนดStudent.prototypeไปObject.create(Person.prototype), Student.prototypeตัวเองแล้วมอบหมายให้Person.prototypeและมองขึ้นไปeve.speciesจะกลับมาhumanในขณะที่เราคาดหวัง สมมุติว่าเราต้องการให้สืบทอดมาจาก Student.prototype และ Person.prototype ดังนั้นเราต้องแก้ไขทั้งหมดนี้
/* This sets up the prototypal delegation correctly 
 *so that if a lookup fails on Student.prototype, it would delegate to Person's .prototype
 *This also allows us to add more things to Student.prototype 
 *that Person.prototype may not have
 *So now a failed lookup on an instance of Student 
 *will first look at Student.prototype, 
 *and failing that, go to Person.prototype (and failing /that/, where do we think it'll go?)
*/
Student.prototype = Object.create(Person.prototype);
ตอนนี้คณะทำงาน แต่เรากำลังเขียนทับกับของStudent.prototype Person.prototypeดังนั้นถ้าเราเรียกStudent.prototype.constructorมันจะชี้ไปแทนPerson นี่คือเหตุผลที่เราจำเป็นต้องแก้ไขStudent
// Now we fix what the .constructor property is pointing to    
Student.prototype.constructor = Student
// If we check instanceof here
console.log(eve instanceof Person) // true
ใน ES5 constructorคุณสมบัติของเราเป็นข้อมูลอ้างอิงที่อ้างอิงถึงฟังก์ชั่นที่เราเขียนด้วยความตั้งใจที่จะเป็น 'ผู้สร้าง' นอกเหนือจากสิ่งที่newคำหลักให้เรา, นวกรรมิกก็เป็นฟังก์ชั่น 'ธรรมดา'
ใน ES6 constructorตอนนี้ถูกสร้างขึ้นในวิธีที่เราเขียนคลาส - ซึ่งเป็นวิธีการเมื่อเราประกาศคลาส นี่เป็นน้ำตาลเชิงประโยคเพียง แต่ให้ความสะดวกกับเราเช่นการเข้าถึงsuperเมื่อเราขยายคลาสที่มีอยู่ ดังนั้นเราจะเขียนโค้ดด้านบนดังนี้:
class Person {
  // constructor function here
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  // static getter instead of a static property
  static get species() {
    return 'human';
  }
}
class Student extends Person {
   constructor(name, age, school) {
      // calling the superclass constructor
      super(name, age);
      this.school = school;
   }
}