Про инициализацию счетчиков Яндекс Метрики и Google API

Яндекс Метрика

(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");

Из необычного используется оператор запятая, эквивалентно:

window.ym = window.ym || function() {
  window.ym.a = window.ym.a || [];
  window.ym.a.push(arguments);
};
window.ym.l = 1 * new Date();
const script = document.createElement('script');
const firstScript = document.getElementsByTagName('script')[0]; // первый <script> в текущем документе
script.async = 1;
script.src = 'https://mc.yandex.ru/metrika/tag.js';
firstScript.parentNode.insertBefore(script, firstScript);

Как нетрудно заметить, у метрики 6 и 7 параметры (k, a) в момент вызова undefined т.е. это своего рода инициализация, чтобы в дальнейшем присвоить document.createElement('script') и document.getElementsByTagName('script')[0] соответственно.

Google API

(function(w,d,s,g,js,fjs){
  g=w.gapi||(w.gapi={});g.analytics={q:[],ready:function(cb){this.q.push(cb)}};
  js=d.createElement(s);fjs=d.getElementsByTagName(s)[0];
  js.src='https://apis.google.com/js/platform.js';
  fjs.parentNode.insertBefore(js,fjs);js.onload=function(){g.load('analytics')};
}(window,document,'script'));

Эквивалентно:

window.gapi = window.gapi || (window.gapi = {});
window.gapi.analytics = {
    q: [], // очередь функций обратного вызова, которые будут выполнены, когда загрузится библиотека
    ready: function(cb) {
      this.q.push(cb);
    },
};
const script = document.createElement('script');
const firstScript = document.getElementsByTagName('script')[0];
script.src = 'https://apis.google.com/js/platform.js';
firstScript.parentNode.insertBefore(script, firstScript);
script.onload = function() {
    window.gapi.load('analytics'); // нужное API, в данном случае аналитика
};

Немного объяснений

Используется IIFE, что позволяет избежать конфликта используемых имён переменных.

(function(_, global, document) {
    // use _ for library, global for window
    // code
}(library, window, document));

Код исполняется также как и без (function(_, global, document) { ... }(library, window, document));, но не загрязняется глобальная область. Также код экранируется от того, что кто-то может случайно изменить используемые переменные.

Лично я до конца не в курсе зачем передавать window и document как параметры, но в этих ваших интернетах пишут следующее:

  • Локальные переменные разрешаются быстрее, чем глобальные т.к. ссылки в IIFE не нужно искать за пределами локальной области видимости.
  • Минификаторы JavaScript могут безопасно минимизировать имена параметров, объявленные в функции.

Похожие записи

RxJs Subjects

Выдержки из доклада Андрея Алексеева (Tinkoff) про RxJs (Subject, Behaviour Subject, Replay Subject, Async Subject). Применение в Angular.

RxJS. Delay from array

import { of, from } from 'rxjs'; 
import { map, concatMap, delay } from 'rxjs/operators';

from([2,4,6,8]).pipe(
  concatMap(item => of(item).pipe(delay(1000)))
).subscribe(console.log);

Добавить css link и js script динамически

const link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = 'https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css';
link.integrity = 'sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO'; // необязательно
link.crossOrigin = 'anonymous'; // необязательно
document.head.appendChild(link);

const script = document.createElement('script');
script.src = 'https://code.jquery.com/jquery-3.3.1.slim.min.js';
script.integrity = 'sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo'; // необязательно
s...