5

Làm cách nào để kiểm tra xem đối tượng JavaScript có đang triển khai giao diện bằng cách sử dụng Google Closure inheritance mechanism không?Kiểm tra xem đối tượng có đang triển khai giao diện trong khung lớp Google Closure


tôi không thể tìm thấy bất kỳ dấu hiệu của my.Animal trong các đối tượng được tạo ra thông qua new my.Dog()object instanceof my.Animal đã không làm việc. Thông tin duy nhất về giao diện là lỗi trình biên dịch khi quên thực hiện các phương thức trong lớp con.

/** 
* @interface 
*/ 
my.Animal = function() {}; 

/** 
* Does something. 
* @return {string} 
*/ 
my.Animal.prototype.doSomething; 

/** 
* @constructor 
* @implements {my.Animal} 
*/ 
my.Dog = function() {}; 

/** @inheritDoc */ 
my.Dog.prototype.doSomething() = function { 
    return "something"; 
} 

var dog = new my.Dog(); 
console.log(dog instanceof my.Animal); // returns false 

Một cách tôi tìm thấy là xấp xỉ thử nghiệm cho các tài sản của các giao diện, mặc dù đó là xấu trong rất nhiều khía cạnh:

console.log(!!dog.doSomething); // returns true 
+2

Tôi rất muốn nhận được nhận xét về những điều sai trái TRƯỚC KHI được giảm giá. –

Trả lời

2

@interface hoàn toàn là cấu trúc trình kiểm tra loại. Trong mã chưa được biên dịch, không có gì có thể kiểm tra các nhận xét cho @interface/@implements để thêm bất kỳ hệ thống dây điện nào để kiểm tra thời gian chạy. Mục tiêu của Closure là mã sẽ chạy giống nhau trước và sau khi biên dịch (giả sử rằng bạn quan sát các hạn chế cho chế độ tối ưu hóa mà bạn đang sử dụng). Các mô hình điển hình khi một tấm séc runtime được mong muốn là để gắn thẻ lớp mà thực hiện giao diện bạn đang quan tâm:

my.Dog.prototype.implements_my_Animal = true; 

sau đó

if (foo.implements_my_Animal) ... 

Đây là một chút khó chịu, do đó bạn không nhìn thấy nó ở đâu nó không cần thiết. Có nhiều cách khác nhau để bọc này nhưng, nếu bạn sử dụng chế độ ADVANCED, hầu hết kết quả trong lớp thực hiện (my.Dog trong ví dụ của bạn) thoát và không thể tháo rời nếu không sử dụng.

+0

Lưu ý: Có lẽ bạn nên thêm một đối tượng sentinel thay vì true và kiểm tra sự tương đương, như '(foo.implements_my_Animal === the_object)' vì nếu không bạn sẽ nhận được các kết quả sai khi một đối tượng xảy ra để xác định cùng một khóa. Điều này có thể dễ dàng xảy ra sau khi biên dịch trước, đổi tên nó thành 'foo.a'. Đây là điều chúng tôi gặp phải trong Clojurescript: https://dev.clojure.org/jira/browse/CLJS-1658 – ClojureMostly

1

Bạn có thể không trực tiếp.

Trong hệ thống kiểu Trình biên dịch đóng gói, @extends được sử dụng để kế thừa và tương quan với các thử nghiệm instanceof. Việc triển khai giao diện được biểu thị bằng @implements hoàn toàn là kiểm tra thời gian biên dịch. Họ là một lời hứa rằng đối tượng của bạn chứa các phương thức và thuộc tính phù hợp với các định nghĩa của giao diện.

Như vậy, để kiểm tra chúng trong thời gian chạy một cách toàn diện, bạn cần phải kiểm tra tính tồn tại và loại của từng thuộc tính của giao diện.

Các vấn đề liên quan