Классы ES6: как насчет инстроспекции?
1557 просмотра
1 ответ
В ES5 я мог проверить существование «класса» (функции конструктора) в объекте окна:
if (window.MyClass) {
... // do something
}
В ES6, согласно этой статье , глобально объявленные классы являются глобальными, а не свойствами глобального объекта ( window
в браузерах):
Но теперь есть и глобальные переменные, которые не являются свойствами глобального объекта. В глобальной области видимости следующие переменные создают следующие объявления:
let
декларацииconst
декларации- Объявления класса
Так что, если я не могу использовать if (window.MyClass)
, есть ли способ сделать то же самое?
На самом деле есть ли правильный способ сделать это без использования оконного объекта?
Автор: Samuel Maisonneuve Источник Размещён: 13.11.2019 11:47Ответы (1)
12 плюса
В ES5 мы могли бы проверить существование класса в объекте окна
Только если функция конструктора была глобальной, что является плохой практикой.
В ES6, согласно этой статье , глобально объявленные классы являются глобальными, а не свойствами глобального объекта ...
Верный. (То же самое верно let
и для const
объявлений в глобальной области видимости.) Это определено в §8.1.1.4: Глобальные записи среды :
Глобальная запись среды логически представляет собой одну запись, но она указывается как составная инкапсуляция объекта записи среды и декларативной записи среды. Объектная запись среды имеет в качестве базового объекта глобальный объект связанной области. Этот глобальный объект является значением, возвращаемым конкретным методом GetThisBinding глобальной записи среды. (Например, глобальный объект, на который ссылается
window
браузер - TJ) Компонент Object Environment Record глобальной записи Environment содержит привязки для всех встроенных глобальных переменных (раздел 18) и все привязки, представленные FunctionDeclaration , GeneratorDeclaration или VariableStatementсодержится в глобальном коде. Привязки для всех других объявлений ECMAScript в глобальном коде содержатся в декларативном компоненте записи среды глобальной записи среды.
(Курсив мой) Так что те вещи , которые используются для перехода на глобальный объект в ES5 и еще раньше делать (плюс генераторы, так как он был бы еще более запутанной , если они не делали), но новые вещи ( let
, const
и class
декларации) не . Они глобальные, но не свойства глобального объекта.
Вернуться к вашему вопросу ...
Так что, если я не могу использовать
if (window.MyClass)
, есть ли способ сделать то же самое?
Вы могли бы использовать
if (typeof MyClass === "function") {
... поскольку typeof
неразрешимый символ не выбрасывает ReferenceError
. Это также имеет преимущество проверки того, MyClass
находится ли область действия кода, даже если она не глобальная.
Там в Гоча есть , хотя: Если этот код находится в той же области , где MyClass
объявлено через class
(или let
или const
) , но это выше MyClass
в этой области видимости, даже typeof
чек будет бросать ReferenceError
, потому что вы не можете получить доступ к связыванию он создает на всех (не даже с typeof
) до class
(или let
или const
).
Например, это бросит:
if (typeof MyClass === "function") { // ReferenceError here
// Yup, it's defined
// ...
}
// ...
class MyClass {
}
Пространство от начала объема к class
, let
или const
линия называется временной мертвой зоной (ТДЗ) и вы не можете получить доступ к переменному связыванию на всех. Следовательно, вы должны поймать ReferenceError
:
let exists = false;
try {
exists = typeof MyClass === "function";
} catch (e) {
}
На самом деле есть ли правильный способ сделать это без использования оконного объекта?
Пока модули JavaScript не дойдут до широкой поддержки браузера, есть несколько способов:
Используйте некоторую библиотеку определения асинхронного модуля для загрузки ваших модулей. Некоторые примеры: RequireJS, SystemJS, CommonJS
Имейте единственную глобальную переменную, которую вы будете использовать для ссылки на объект, и задайте своим глобальным свойствам приложения этот объект. Вот типичный способ сделать это:
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... } }({}); }
Это также дает вам удобную область (анонимную функцию), в которую можно помещать любые глобальные переменные уровня модуля.
Автор: T.J. Crowder Размещён: 19.05.2015 09:51Вопросы из категории :
- javascript Как определить, какой из указанных шрифтов был использован на веб-странице?
- javascript Валидация клиентской стороны ASP.Net
- javascript Длина объекта JavaScript
- javascript Получение текста из выпадающего списка
- javascript Скрипт входа со скрытыми кнопками
- class В чем разница между структурой и классом в .NET?
- class Когда вы должны использовать класс против структуры в C ++?
- class В чем разница между старым и новым стилем классов в Python?
- class Как сделать глубокую копию объекта в Java?
- class Возможны ли статические переменные класса?
- ecmascript-6 What's the difference between using "let" and "var" to declare a variable in JavaScript?
- ecmascript-6 Конечно, у ES6 + должен быть способ объединить два объекта javascript вместе, что это?
- ecmascript-6 Расширяющий класс JavaScript
- ecmascript-6 Что делают фигурные скобки в выражениях `var {...} = ...`?
- ecmascript-6 let keyword in the for loop
- introspection Нахождение каких методов у объекта Python
- introspection Есть ли встроенная функция для печати всех текущих свойств и значений объекта?
- introspection Получение имен параметров метода в Python
- introspection Получение имени класса экземпляра?
- introspection Как вы можете напечатать имя переменной в Python?