В JavaScript много странностей и сложного для понимания поведения. Есть веселые разговоры, такие как WTFJS и WAT, которые высмеивают JavaScript за его странности.
Поскольку я занимаюсь рефакторингом, мне приходится учитывать множество странных, а иногда и забавных сторон JavaScript. Я поделюсь некоторыми из удивительных поведений, с которыми сталкиваюсь, поэтому, если вы их увидите (чего, надеюсь, никогда не увидите), это может намекнуть на то, что происходит.
Этот пост в блоге исследует невинное заявление:
// ... some code
helloWorld;
Вы можете интуитивно подумать, что здесь ничего не должно происходить — кажется, что оператор ничего не делает, потому что здесь нет очевидного вызова функции.
Однако он может делать что угодно, например, печатать «Hello World!» к консоли.
// ... some code
helloWorld; // prints "Hello World!"
Как это вообще возможно?
Получается, что глобальные переменные (в данном случае helloWorld
) являются свойствами глобального объекта. И свойства в JavaScript не обязательно должны быть простыми значениями. Их можно реализовать с помощью геттеров и сеттеров, которые могут выполнять код. Поскольку в современных механизмах JavaScript глобальный объект наследуется от Object.prototype
, добавление свойств к Object.prototype
создает свойства глобального объекта.
Здесь helloWorld
определяется как геттер:
Object.defineProperty(Object.prototype, 'helloWorld', { get() { console.log("Hello World!"); }, });
helloWorld; // prints "Hello World!"
К счастью, это может произойти только с глобальными переменными, а не с параметрами или локальными переменными.
Object.defineProperty(Object.prototype, 'helloWorld', { get() { console.log("Hello World!"); }, });
const a = helloWorld; // getter is evaluated, prints "Hello World!" a; // does nothing
Я узнал об этом странном поведении в сообщении в блоге о полифилле globalThis
. В полифилле для доступа к глобальному объекту this
в различных средах, таких как браузеры, веб-воркеры, фреймы, модули Node.js и ES, используется метод получения глобальных свойств. Посмотрите, если хотите узнать больше!