class
Sintaks baru , untuk saat ini , sebagian besar adalah gula sintaksis. (Tapi, Anda tahu, baik jenis gula.) Tidak ada dalam ES2015-ES2020 yang class
dapat melakukan itu Anda tidak dapat melakukan dengan fungsi konstruktor dan Reflect.construct
(termasuk subclassing Error
dan Array
¹). (Ini adalah kemungkinan akan ada beberapa hal dalam ES2021 yang dapat Anda lakukan dengan class
bahwa Anda tidak bisa melakukan sebaliknya: bidang swasta , metode swasta , dan bidang statis / metode statis pribadi .)
Selain itu, apakah class
jenis OOP yang berbeda atau masih merupakan warisan prototipe JavaScript?
Ini adalah warisan prototipe yang sama yang selalu kita miliki, hanya dengan sintaks yang lebih bersih dan nyaman jika Anda suka menggunakan fungsi konstruktor ( new Foo
, dll.). (Khususnya dalam hal mengambil dari Array
atau Error
, yang tidak dapat Anda lakukan di ES5 dan sebelumnya. Sekarang Anda dapat melakukannya dengan Reflect.construct
[ spec , MDN ], tetapi tidak dengan gaya ES5 yang lama.)
Bisakah saya memodifikasinya menggunakan .prototype
?
Ya, Anda masih bisa memodifikasi prototype
objek pada konstruktor kelas setelah Anda membuat kelas. Misalnya, ini legal:
class Foo {
constructor(name) {
this.name = name;
}
test1() {
console.log("test1: name = " + this.name);
}
}
Foo.prototype.test2 = function() {
console.log("test2: name = " + this.name);
};
Apakah ada manfaat kecepatan?
Dengan memberikan idiom khusus untuk ini, saya kira mungkin saja mesinnya dapat melakukan pengoptimalan pekerjaan yang lebih baik. Tapi mereka sudah sangat pandai dalam mengoptimalkan, saya tidak mengharapkan perbedaan yang signifikan.
Manfaat apa yang disediakan class
sintaks ES2015 (ES6) ?
Singkatnya: Jika Anda tidak menggunakan fungsi konstruktor pada awalnya, lebih suka Object.create
atau serupa, class
tidak berguna bagi Anda.
Jika Anda menggunakan fungsi konstruktor, ada beberapa keuntungan untuk class
:
Sintaksnya lebih sederhana dan tidak terlalu rentan terhadap kesalahan.
Jauh lebih mudah (dan sekali lagi, lebih sedikit rawan kesalahan) untuk menyiapkan hierarki pewarisan menggunakan sintaks baru daripada dengan yang lama.
class
melindungi Anda dari kesalahan umum karena gagal menggunakan new
fungsi konstruktor (dengan meminta konstruktor melontarkan pengecualian jika this
bukan objek yang valid untuk konstruktor).
Memanggil versi metode prototipe induk jauh lebih sederhana dengan sintaks baru daripada yang lama ( super.method()
bukan ParentConstructor.prototype.method.call(this)
atau Object.getPrototypeOf(Object.getPrototypeOf(this)).method.call(this)
).
Berikut perbandingan sintaks untuk hierarki:
class Person {
constructor(first, last) {
this.first = first;
this.last = last;
}
personMethod() {
}
}
class Employee extends Person {
constructor(first, last, position) {
super(first, last);
this.position = position;
}
employeeMethod() {
}
}
class Manager extends Employee {
constructor(first, last, position, department) {
super(first, last, position);
this.department = department;
}
personMethod() {
const result = super.personMethod();
return result;
}
managerMethod() {
}
}
Contoh:
class Person {
constructor(first, last) {
this.first = first;
this.last = last;
}
personMethod() {
return `Result from personMethod: this.first = ${this.first}, this.last = ${this.last}`;
}
}
class Employee extends Person {
constructor(first, last, position) {
super(first, last);
this.position = position;
}
personMethod() {
const result = super.personMethod();
return result + `, this.position = ${this.position}`;
}
employeeMethod() {
}
}
class Manager extends Employee {
constructor(first, last, position, department) {
super(first, last, position);
this.department = department;
}
personMethod() {
const result = super.personMethod();
return result + `, this.department = ${this.department}`;
}
managerMethod() {
}
}
const m = new Manager("Joe", "Bloggs", "Special Projects Manager", "Covert Ops");
console.log(m.personMethod());
vs.
var Person = function(first, last) {
if (!(this instanceof Person)) {
throw new Error("Person is a constructor function, use new with it");
}
this.first = first;
this.last = last;
};
Person.prototype.personMethod = function() {
};
var Employee = function(first, last, position) {
if (!(this instanceof Employee)) {
throw new Error("Employee is a constructor function, use new with it");
}
Person.call(this, first, last);
this.position = position;
};
Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;
Employee.prototype.employeeMethod = function() {
};
var Manager = function(first, last, position, department) {
if (!(this instanceof Manager)) {
throw new Error("Manager is a constructor function, use new with it");
}
Employee.call(this, first, last, position);
this.department = department;
};
Manager.prototype = Object.create(Employee.prototype);
Manager.prototype.constructor = Manager;
Manager.prototype.personMethod = function() {
var result = Employee.prototype.personMethod.call(this);
return result;
};
Manager.prototype.managerMethod = function() {
};
Contoh Langsung:
var Person = function(first, last) {
if (!(this instanceof Person)) {
throw new Error("Person is a constructor function, use new with it");
}
this.first = first;
this.last = last;
};
Person.prototype.personMethod = function() {
return "Result from personMethod: this.first = " + this.first + ", this.last = " + this.last;
};
var Employee = function(first, last, position) {
if (!(this instanceof Employee)) {
throw new Error("Employee is a constructor function, use new with it");
}
Person.call(this, first, last);
this.position = position;
};
Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;
Employee.prototype.personMethod = function() {
var result = Person.prototype.personMethod.call(this);
return result + ", this.position = " + this.position;
};
Employee.prototype.employeeMethod = function() {
};
var Manager = function(first, last, position, department) {
if (!(this instanceof Manager)) {
throw new Error("Manager is a constructor function, use new with it");
}
Employee.call(this, first, last, position);
this.department = department;
};
Manager.prototype = Object.create(Employee.prototype);
Manager.prototype.constructor = Manager;
Manager.prototype.personMethod = function() {
var result = Employee.prototype.personMethod.call(this);
return result + ", this.department = " + this.department;
};
Manager.prototype.managerMethod = function() {
};
var m = new Manager("Joe", "Bloggs", "Special Projects Manager", "Covert Ops");
console.log(m.personMethod());
Seperti yang Anda lihat, banyak hal berulang dan bertele-tele di sana yang mudah salah dan membosankan untuk diketik ulang (itulah sebabnya saya menulis skrip untuk melakukannya , dulu).
¹ "Tidak ada dalam ES2015-ES2018 yang class
dapat melakukan hal yang tidak dapat Anda lakukan dengan fungsi konstruktor dan Reflect.construct
(termasuk subclassing Error
danArray
)"
Contoh:
function MyError(...args) {
return Reflect.construct(Error, args, this.constructor);
}
MyError.prototype = Object.create(Error.prototype);
MyError.prototype.constructor = MyError;
MyError.prototype.myMethod = function() {
console.log(this.message);
};
function outer() {
function inner() {
const e = new MyError("foo");
console.log("Callng e.myMethod():");
e.myMethod();
console.log(`e instanceof MyError? ${e instanceof MyError}`);
console.log(`e instanceof Error? ${e instanceof Error}`);
throw e;
}
inner();
}
outer();
.as-console-wrapper {
max-height: 100% !important;
}