typescript - Tại sao instanceof trả về false cho một đối tượng con trong Javascript
Tôi có lớp Child kế thừa lớp Parent. Giả sử tôi tạo một thể hiện mới 'child' từ lớp Child. Khi tôi kiểm tra điều kiện child instanceof Child, nó trả về false. Tuy nhiên, child instanceof Parent thì trả về true.
Tại sao lại như vậy?
CHỈNH SỬA
Vì vậy tôi nhận thấy điều này chỉ xảy ra khi tôi mở rộng lớp Child với lớp Error. Hãy để tôi để ví dụ mã bên dưới.
class Child extends Error {
constructor(message) {
super(message);
}
}
const ch = new Child();
console.log(ch instanceof Child);ĐIỀU SỬA ĐỔI THỨ HAI
class PullCreditError extends Error {
public name: string;
public message: string;
public attemptsRemaining: number;
constructor(message: string, attemptsRemaining: number) {
super();
Error.captureStackTrace(this, PullCreditError);
this.name = 'PullCreditError';
this.message = message;
this.attemptsRemaining = attemptsRemaining;
}
}
Câu trả lời #1
Đây là một lỗi đã được ghi nhận:
https://github.com/Microsoft/TypeScript/issues/15875
Mở rộng các đối tượng tích hợp sẵn như Error, Array và Map có thể không còn hoạt động nữa
Như một phần của việc thay thế giá trị của this bằng giá trị trả về bởi một lời gọi super(...), việc kế thừa từ Error, Array và các lớp khác có thể không còn hoạt động như mong đợi. Điều này là do các hàm tạo cho Error, Array và các lớp tương tự sử dụng new.target của ECMAScript 6 để điều chỉnh chuỗi prototype; tuy nhiên, không có cách nào để đảm bảo giá trị cho new.target khi gọi một hàm tạo trong ECMAScript 5. Các trình biên dịch cấp thấp khác thường cũng có hạn chế tương tự theo mặc định.
Khuyến nghị là điều chỉnh nguyên mẫu thủ công bằng setPrototypeOf trong hàm khởi tạo. Một cách sửa cho lớp PullCreditError của bạn sẽ trông như sau:
export class PullCreditError extends Error {
public name: string;
public message: string;
public attemptsRemaining: number;
constructor(message: string, attemptsRemaining: number) {
super();
Object.setPrototypeOf(this, PullCreditError.prototype); // <-------
Error.captureStackTrace(this, PullCreditError);
this.name = 'PullCreditError';
this.message = message;
this.attemptsRemaining = attemptsRemaining;
}
}
