Mới class
cú pháp là, đối với doanh nghiệp , chủ yếu là đường cú pháp. (Nhưng bạn biết đấy, loại tốt .) Không có gì trong ES2015-ES2020 class
có thể làm được điều mà bạn không thể làm với các hàm khởi tạo và Reflect.construct
(bao gồm phân lớp Error
và Array
¹). (Đó là khả năng sẽ có một số điều trong ES2021 mà bạn có thể làm với class
rằng bạn không thể làm khác: lĩnh vực tư nhân , các phương pháp riêng , và các lĩnh vực tĩnh / phương pháp tĩnh tin .)
Hơn nữa, là class
một loại OOP khác hay nó vẫn là sự kế thừa nguyên mẫu của JavaScript?
Đó là sự kế thừa nguyên mẫu mà chúng ta luôn có, chỉ với cú pháp rõ ràng và thuận tiện hơn nếu bạn thích sử dụng các hàm khởi tạo ( new Foo
, v.v.). (Đặc biệt trong trường hợp bắt nguồn từ Array
hoặc Error
, điều mà bạn không thể làm trong ES5 trở về trước. Giờ đây, bạn có thể với Reflect.construct
[ spec , MDN ], nhưng không thể với kiểu ES5 cũ.)
Tôi có thể sửa đổi nó bằng cách sử dụng .prototype
không?
Có, bạn vẫn có thể sửa đổi prototype
đối tượng trên phương thức khởi tạo của lớp sau khi bạn đã tạo lớp. Ví dụ: điều này hoàn toàn hợp pháp:
class Foo {
constructor(name) {
this.name = name;
}
test1() {
console.log("test1: name = " + this.name);
}
}
Foo.prototype.test2 = function() {
console.log("test2: name = " + this.name);
};
Có lợi ích về tốc độ không?
Bằng cách cung cấp một thành ngữ cụ thể cho điều này, tôi cho rằng có thể động cơ có thể thực hiện công việc tối ưu hóa tốt hơn. Nhưng họ đã rất giỏi trong việc tối ưu hóa rồi, tôi sẽ không mong đợi sự khác biệt đáng kể.
class
Cú pháp ES2015 (ES6) cung cấp những lợi ích gì ?
Tóm lại: Nếu bạn không sử dụng các hàm khởi tạo ngay từ đầu, thì việc ưu tiên Object.create
hoặc tương tự class
sẽ không hữu ích cho bạn.
Nếu bạn sử dụng các hàm khởi tạo, có một số lợi ích class
sau:
Cú pháp đơn giản hơn và ít lỗi hơn.
Việc thiết lập cấu trúc phân cấp kế thừa bằng cú pháp mới sẽ dễ dàng hơn nhiều (và một lần nữa, ít mắc lỗi hơn) so với cách sử dụng cú pháp cũ.
class
bảo vệ bạn khỏi lỗi phổ biến khi không sử dụng được new
với hàm tạo (bằng cách để hàm tạo ném một ngoại lệ nếu this
không phải là đối tượng hợp lệ cho hàm tạo).
Việc gọi phiên bản nguyên mẫu gốc của một phương thức đơn giản hơn nhiều với cú pháp mới so với cú pháp cũ ( super.method()
thay vì ParentConstructor.prototype.method.call(this)
hoặc Object.getPrototypeOf(Object.getPrototypeOf(this)).method.call(this)
).
Đây là một so sánh cú pháp cho một hệ thống phân cấp:
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() {
}
}
Thí dụ:
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() {
};
Ví dụ trực tiếp:
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());
Như bạn có thể thấy, rất nhiều thứ lặp đi lặp lại và dài dòng ở đó, rất dễ nhập sai và nhàm chán khi gõ lại (đó là lý do tại sao tôi đã viết một kịch bản để làm điều đó , trước đó).
¹ "Không có gì trong ES2015-ES2018 class
có thể làm mà bạn không thể làm với các hàm khởi tạo và Reflect.construct
(bao gồm cả phân lớp Error
và Array
)"
Thí dụ:
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;
}