Оглавление

Небольшая памятка по JavaScript

Написано для себя и команды.

Не забывайте var

Только так можно избежать глобальных переменных.

Используйте === а не ==

Не пытайтесь запомнить, что [7] == 7 — это true, что '7' == 7 и [] == 0 — это тоже true. Запомнить все нюансы невозможно. Просто запомните, что поведение == весьма коварно. Используйте ===.

Используйте ; вместо переводов строк

Знайте, что JavaScript использует своеобразный препроцессинг, чтобы расставить ; за вас (ASI — Automatic Semicolon Insertion). Этот препроцессинг может вести себя не так, как вы ожидаете. Например

function f() {
  return
  [1, 2, 3]
}

Вернёт undefined, так как после return будет добавлена ;.

Будьте очень осторожны с typeof, instanceof и constructor

typeof []'object', typeof null — тоже 'object' и не только это.

Не брезгуйте Self-calling Function

Это позволяет максимально разделить области видимости переменных.

Не забывайте преобразовывать arguments в массив

var argArray = Array.prototype.slice.call(arguments);

При проверке, что переменная число, не забывайте про NaN и Infinity

!isNaN(parseFloat(n)) && isFinite(n);

Когда создаёте замыкания, помните, что замыкается весь контекст

Если в контексте есть много переменных, ссылки на DOM или другие тяжёлые объекты, то при создании замыканий следует ограничить число переменных для замыкания только необходимыми.

function big_function() {
  // много переменных, среди которых есть some_data
  var some_data;
  /*
  это плохо, так как в f замкнутся все переменные из контекста,
  а не только some_data
  function f() {
    console.log(some_data);
  }
  */
  // а это хорошо
  var f = (function(some_data) {
    return function() {
      console.log(some_data);
    }
  }(some_data));
}

Не забывайте, что var работает в начале области видимости

При активном использовании замыканий, разграничении скоупов и создании вложенных скоупов (все эти приёмы полезны) надо быть осторожным с лишними var и помнить об их неявном выполнении вначале области видимости.

В этом примере разработчик постарался замкнуть переменную x со значением true.

var f = (function(x) {
  return function() {
    console.log(x);
    if (x) {
      var x = 2;
    }
    console.log(x);
  }
}(true));

f();

Если бы перед x не было бы var, то код сработал бы так, как задумал автор:

true
2

Однако, несмотря на то, что во внешнем скоупе x=true, ветка if выполнена не будет. И невзирая на то, что она выполнена не будет, var x всё же сработает. Результат будет таким:

undefined
undefined

Всё это случится потому, что этот код будет интерпретирован так:

var f = (function(x) {
  return function() {
    var x; // x = undefined
    console.log(x); // будет напечатано "undefined"
    if (x) {
      // ветка не сработает
      x = 2;
    }
    console.log(x); // будет напечатано "undefined"
  }
}(true));

f();

var работает не там, где написан и не тогда, когда выполнение доходит до него.

Не забывайте про полезные методы jQuery (или других библиотек)

$.each, $.map, $.proxy, $.extend, $.grep, $.merge, $.now, $.parseJSON… Они компактны, надёжны, переносимы. Нативные JavaScript-методы, обеспечивающие аналогичную функциональность, оказываются доступны не всегда.