2015-05-19 18 views
6

Trong ES5, tôi có thể kiểm tra sự tồn tại của một "lớp" (hàm xây dựng) trên đối tượng cửa sổ:Các lớp ES6: điều gì về sự thiếu hiểu biết?

if (window.MyClass) { 
... // do something 
} 

Trong ES6, according to this article, các lớp học toàn cầu tuyên bố là globals, nhưng không phải thuộc tính của đối tượng toàn cầu (window, trên trình duyệt):

Nhưng hiện tại cũng có biến toàn cầu không thuộc tính của đối tượng chung. Trong phạm vi toàn cầu, các tờ khai sau tạo ra các biến như:

  • let tờ khai
  • const tờ khai
  • tờ khai Lớp

Vì vậy, nếu tôi không thể sử dụng if (window.MyClass), là có một cách để làm cái tương tự?

Thực sự là có cách thích hợp để thực hiện việc này mà không cần sử dụng đối tượng cửa sổ?

+4

"có nghĩa là chúng không thể truy cập được trên phạm vi toàn cầu của cửa sổ" ... Điều gì khiến cho việc nâng cấp phải phù hợp với phạm vi toàn cầu? – elclanrs

+0

Cảm ơn câu trả lời của bạn. Thật vậy, xin lỗi vì sự nhầm lẫn, không có gì để xem với cẩu. Dù sao, bạn có đề nghị nào để kiểm tra sự tồn tại của lớp không? es6 mô-đun có thể? – Sam

+0

Kiểm tra xem mô-đun gốc khai báo lớp được khai báo? –

Trả lời

6

Trong ES5, chúng ta có thể wheck sự tồn tại của một lớp học trên đối tượng cửa sổ

Chỉ khi hàm xây dựng là một toàn cầu, đó là thực hành kém.

Trong ES6, according to this article, các lớp học toàn cầu tuyên bố là globals, nhưng không phải thuộc tính của đối tượng toàn cầu ...

đúng. (Điều này cũng đúng của letconst tờ khai ở phạm vi toàn cầu.) Này được định nghĩa trong §8.1.1.4: Global Environment Records:

Một Ghi Môi trường toàn cầu là hợp lý một hồ sơ duy nhất nhưng nó được quy định như một hỗn hợp đóng gói một Ghi Môi trường đối tượng và một bản ghi môi trường khai báo. Đối tượng Environment Record có đối tượng cơ sở của nó là đối tượng toàn cầu của Realm có liên quan. Đối tượng toàn cầu này là giá trị được trả về bởi phương thức bê tông GetThisBinding của Bản ghi môi trường toàn cầu. (Ví dụ, đối tượng toàn cầu được tham chiếu bởi window trên các trình duyệt   — TJ)Đối tượng Ghi Môi trường thành phần của bản ghi Môi trường toàn cầu bao gồm các cam kết ràng buộc đối với tất cả built-in globals (khoản 18) và tất cả các ràng buộc được giới thiệu bởi một FunctionDeclaration , GeneratorDeclaration hoặc VariableStatement chứa trong mã toàn cầu. Các ràng buộc cho tất cả các khai báo ECMAScript khác trong mã toàn cầu được chứa trong thành phần khai báo môi trường bản ghi của bản ghi môi trường toàn cầu.

(nhấn mạnh của tôi) Vì vậy, những điều mà sử dụng để đi trên đối tượng toàn cầu trong ES5 và trước đó vẫn làm (cộng với máy phát điện, vì nó đã khó hiểu hơn nếu họ không làm), nhưng mới điều (let, constclass tuyên bố) không. Chúng là các hình cầu, nhưng không phải là các thuộc tính của đối tượng toàn cầu.

Về câu hỏi của bạn ...

Vì vậy, nếu tôi không thể sử dụng if (window.MyClass), là có một cách để làm như vậy?

Bạn có thể sử dụng

if (typeof MyClass === "function") { 

... kể từ typeof trên một biểu tượng không thể giải quyết không ném một ReferenceError. Điều này cũng có lợi thế là kiểm tra xem MyClass có nằm trong phạm vi mã hay không, ngay cả khi đó là không phải là toàn cầu.

Có một Gotcha có mặc dù: Nếu mã số đó là trong phạm vi cùng một nơi MyClass được khai báo qua class (hoặc let hoặc const) nhưng nó trênMyClass trong phạm vi đó, ngay cả việc kiểm tra typeof sẽ ném một ReferenceError, bởi vì bạn không thể truy cập vào liên kết mà nó tạo ra tại tất cả (thậm chí không với typeof) trước số class (hoặc let hoặc const).

Ví dụ, điều này sẽ ném:

if (typeof MyClass === "function") { // ReferenceError here 
    // Yup, it's defined 
    // ... 
} 
// ... 
class MyClass { 
} 

Không gian từ khi bắt đầu phạm vi đến class, let, hoặc const dòng được gọi là thời vùng chết (TDZ) và bạn có thể không truy cập vào biến ràng buộc ở tất cả. Do đó, bạn phải bắt ReferenceError:

let exists = false; 
try { 
    exists = typeof MyClass === "function"; 
} catch (e) { 
} 

Trên thực tế là có một cách thích hợp để làm điều này mà không cần sử dụng đối tượng cửa sổ?

Cho đến module JavaScript làm cho nó để hỗ trợ trình duyệt rộng, có một vài cách sau:

  1. Sử dụng một thư viện Definition Asynchronous Mô-đun của một số loại để xử lý tải module của bạn. Một số ví dụ: RequireJS, SystemJS, CommonJS

  2. Có một biến toàn cầu duy nhất mà bạn sẽ sử dụng để tham chiếu đến một đối tượng và tạo các thuộc tính globals ứng dụng khác nhau của đối tượng đó.Dưới đây là một cách điển hình để làm điều đó:

    var MyApp = MyApp || {}; 
    if (!MyApp.ThisModule) {     // You can leave this `if` out 
                  // if there's no chance of the file 
                  // being loaded more than once 
        MyApp.ThisModule = function(module) { 
         module.MyClass = class MyClass { 
          // ...class definition here... 
         } 
        }({}); 
    } 
    

này cũng cung cấp cho bạn một phạm vi tiện dụng (anonymous function) trong đó để đặt bất kỳ globals mô-đun cấp.

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