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 let
và const
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
, const
và class
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:
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
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ó 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
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
Kiểm tra xem mô-đun gốc khai báo lớp được khai báo? –