JavaScript должен быть написан на компьютере. Само собой разумеется. Но в 2011 году во время моего последнего выпускного экзамена мне пришлось вручную писать функции JavaScript.

Да, мне физически приходилось писать циклы, переменные, селекторы и даже:

document.getElementById();

И я ненавидел писать это. Это заняло так много места на моей бумаге. Я даже не шучу. Иди напиши это. Функции JavaScript никогда не следует писать на бумаге.

Вместо этого я сделал что-то вроде этого:

function getId(id) {
   return document.getElementById(id);
}

И если мне это было нужно, я просто звонил getId(). Еще я сделал его для getClass(), потому что я ботаник.

Год спустя я изучил jQuery, и теперь моя функция getId() стала:

jQuery('#id');

Тот факт, что я мог также использовать селекторы CSS, поразил меня. Я мог бы сделать вот что:

jQuery('.list:first-child ~ li[icon*="fa-"]'); 

и это сработало! jQuery открывает столько возможностей!

Но это было в 2011 году. Теперь наступил 2021 год. Люди по-прежнему постоянно используют jQuery, но сейчас это похоже на темное черное искусство. А, jQuery? Да, просто сделай это ... Но почему бы вместо этого не использовать Vanilla.js? Он работает намного лучше.

И это честно. Благодаря таким вещам, как document.querySelector() и document.querySelectorAll(), теперь мы можем использовать селекторы CSS в обычном JavaScript. Вы даже можете использовать document.querySelector() для замены document.getElementById(), если хотите. Разница в том, что первая работает со скоростью 15 миллионов звонков в секунду, а вторая - со скоростью 7 миллионов звонков в секунду.

Которые, конечно, оба очень быстрые.

Но что, если бы был более быстрый способ? Тот, в котором не было document.getElementById()? Тот, который, если бы мой учитель выполнял свою работу в высшем учебном заведении, мне даже не нужно было бы делать getId()?

Что ж, есть.

Пожалуйста, примите во внимание следующее:

<div id="myElement"><div>
<script>
console.log(myElement);
</script>

Когда вы создаете элемент HTML с использованием идентификатора, уже создается глобальное пространство имен. Нет никакой причины использовать document.getElementById(). Я знаю, это супер круто. Но есть несколько минусов.

Во-первых, это «плохая практика». Это пережиток времен Browser Wars, и хотя он все еще поддерживается сегодня, его не рекомендуется использовать. В нескольких документах, которые я прочитал, говорится, что это также может привести к «хрупкому» коду, что имеет «хрупкий» смысл (ха), потому что если вы добавите эту строку:

var myElement = 'whatever';

Вы теряете доступ к своей глобальной переменной. Но то же самое буквально для всего с JavaScript. Если вы сделаете это:

var overwritable = 'whatever';
var overwritable = 'whatever yourself';
console.log(overwritable);

Он регистрирует whatever yourself. Так что это не более хрупко, чем уже есть JavaScript.

Также существует проблема, что некоторые люди являются монстрами и используют дефисы вместо camelCase (или, idk, подчеркивания?) При идентификации своих элементов. В имени переменной JavaScript не может быть дефиса, поэтому это будет сломано.

Но мы сейчас рассмотрим этот вопрос.

Если вы действительно проверите скорость между этими двумя:

<div id="myElement"></div>
<div id="myElement2"></div>
<script>
var a = performance.now();
console.log(myElement);
var b = performance.now();
var c = performance.now();
console.log(document.getElementById('myElement2'));
var d = performance.now();
console.log("Global call took " + (b - a) + " milliseconds.");
console.log("By Id call took " + (d - c) + " milliseconds.");
</script>

Вы увидите, что document.getElementById() работает примерно в 2 раза быстрее. Итак, глобальная переменная не быстрее.

Но…

Причина этого в том, что доступ к глобальным переменным выполняется медленно. Ему необходимо проанализировать объект window, найти значение и затем вернуть его. Так что, если мы не сделаем его глобальным? Что, если мы сделаем это местным?

const fasterMyPrecious = myElement;

И мы выбрали const, потому что не хотим «ломкого кода» или чего-то еще, чтобы его нельзя было перезаписать. Это также решило проблему с дефисом, поскольку мы должны назвать нашу локальную переменную.

Итак, как это работает сейчас? Что ж, он варьируется между каждым вызовом на ± 0,01 миллисекунды каждый раз, когда запускается скрипт, поэтому, если мы поместим его в цикл и запустим его 1000 раз, мы получим:

Global call took 88.68000004440546 milliseconds.
By Id call took 92.66000072238967 milliseconds.

"Но это несправедливо!" Вы кричите. «fasterMyPrecious кэшируется, а document.getElementById() - нет».

«Хорошо», - отвечаю я. "Тогда давайте закэшируем их обоих".

Наш текущий рабочий сценарий выглядит следующим образом:

<div id="myElement"></div>
<div id="myElement2"></div>
<script>
const fasterMyPrecious = myElement;
const cachedById = document.getElementById('myElement2');
var a, b, c, d;
a = b = c = d = 0;
console.log('start');
for (var i = 0; i < 1000; i++) {
a += performance.now();
console.log(fasterMyPrecious);
b += performance.now();
c += performance.now();
console.log(cachedById); 
d += performance.now();
}
console.log("Global call took " + (b - a) + " milliseconds.");
console.log("By Id call took " + (d - c) + " milliseconds.");
</script>

Результат:

Global call took 88.55000001494773 milliseconds.
By Id call took 91.63999947486445 milliseconds.

Но вот крестраж в целом. Если мы перевернем скрипт и поместим cachedById выше fasterMyPrecious:

<div id="myElement"></div>
<div id="myElement2"></div>
<script>
const fasterMyPrecious = myElement;
const cachedById = document.getElementById('myElement2');
var a, b, c, d;
a = b = c = d = 0;
console.log('start');
for (var i = 0; i < 1000; i++) {
//now above
c += performance.now();
console.log(cachedById); 
d += performance.now();
//now below
a += performance.now();
console.log(fasterMyPrecious);
b += performance.now();
}
console.log("Global call took " + (b - a) + " milliseconds.");
console.log("By Id call took " + (d - c) + " milliseconds.");
</script>

Они распечатывают cachedById (он же document.getElementById) быстрее.

Global call took 92.1750005800277 milliseconds.
By Id call took 89.70999921439216 milliseconds.

Хорошо, хорошо, хорошо. Но что, если мы запустим их независимо друг от друга? Тогда получаем следующее:

By Id call took 93.04500030702911 milliseconds.
Global call took 86.50500001385808 milliseconds.

С fasterByPrecious (он же глобальный селектор пространства имен) на 6,54000029317 миллисекунд быстрее.

Конечно, это незначительное различие можно объяснить буквально чем угодно. Даже сетевой пинг может сбить это с толку. Итак, я сделал немыслимое, отключил свой Интернет (так как вам не нужен Интернет для запуска JavaScript) и снова запустил его:

By Id call took 98.13499977462925 milliseconds.
Global call took 94.89000029861927 milliseconds.

И fasterMyPrecious снова чемпион.

Таким образом, хотя может быть более быстрое решение, чем document.getElementById(), я действительно не уверен, что вы будете делать со всем этим свободным временем.