...

пятница, 18 декабря 2015 г.

Шорткаты в JavaScript

Изучая любой язык программирования, полезно знать о его особенностях и уметь эффективно использовать языковые конструкции. Хочу поделиться с вами шорткатами для JS. Эти сокращения в некоторых случаях могут облегчить чтение кода, а также существенно уменьшить его количество. Однако следует помнить, что они могут сыграть с вами злую шутку и, если использовать их повсеместно, ваш код перестанет быть читаемым и поддерживаемым.


Начнем с простого и достаточно часто встречающегося совета — использовать while вместо for.
var count = foo.length
while (count--) {
// whatever
}
var count = foo.length
for(var i = 0; i < count; i++) {
// whatever
}


Конечно, мне тоже нравится использовать forEach и map, однако в случаях, когда это неуместно, while выглядит более органично и читаемо. К слову, применение переменной для хранения длины массива более производительно, чем вычисление этого значения в каждой итерации.
Традиционно конструкцию for-in используют для итерации объектов, но не нужно забывать, что ею можно воспользоваться и для обычного массива. И хотя в документации указано, что for-in не гарантирует консистентность перебора, на практике я не встречал подобной ситуации.
var count = foo.length
for(var i = 0; i < count; i++) {
// whatever foo[i]
}
for(var i in foo) {
// whatever foo[i]
}


Иногда требуется привести значение к булеву типу, и я покажу традиционное решение этой задачи, а также ее короткую форму:
var foo = Boolean(bar); var foo = !!bar;


Двойное отрицание работает так же, как и приведение, однако справедливо заметить, что, как и в случае со всеми остальными шорткатами, у новичков (да и не только) могут возникнуть сложности в восприятии такого кода.
Есть очень простой способ округлить любое число до ближайшего целого:
var intNum = Math.floor(anyNum); var intNum = ~~anyNum;


Двойное побитовое отрицание работает как Math.floor() для положительных чисел и как Math.ceil() для отрицательных. Объяснение, как это работает, можно найти тут. Читать сложнее, но экономит десять символов.
Даже для true и false можно сделать шорткат. Это выглядит уже совсем за гранью добра и зла, но раз уж мы начали эту тему, то почему бы и нет:
var foo = true,
    bar = false;
var foo = !0,
    bar = !1;


Но это, как ни крути, скорее антишорткат, потому как совершенно нечитаем, требует вычисления со стороны JS, да и вообще выглядит обескураживающе.
Наверняка все знакомы с тернарным оператором, но не все знают, насколько удобным может быть его использование.
if (condition) {
  foo = bar;
} else {
  foo = baz;
}
foo = (condition ? bar : baz);


Уже неплохо, но можно пойти и дальше и использовать его в несколько строк:
if (age > 18) {
  alert("OK, you can go.");
  location.assign("continue.html");
} else {
  location.assign("backToSchool.html");
}
age > 18 ? (
    alert("OK, you can go."),
    location.assign("continue.html")
) : (
    location.assign("backToSchool.html");
);


Тут есть небольшой нюанс: нужно помнить, что операторы в этом случае должны быть разделены запятой, а не точкой с запятой. Другая замечательная особенность этого оператора — он возвращает значение (это было видно из первого примера), а значит, его можно использовать и с функциями.
if (condition) {
  function1();
} else {
  function2();
}
(condition ? function1 : function2)();


Не все помнят, как работает AND, — сначала он вычисляет первое значение и, только если оно равно true, вычисляет другое. Посмотрим, как это можно применить.
if (foo) {
  bar();
}
if (foo) bar();
if (foo) bar();
foo && bar();


Вкупе с OR можно добиться полного эквивалента if-else, но это не стоит того, во что превратится ваш код.
var foo = parseFloat('3133.7'),
    bar = parseInt('31337');


Короткая форма этой записи достаточно проста и элегантна:
var foo = +'3133.7',
    bar = +'31337';


Для обратной задачи тоже есть свой шорткат.
Тут можно продемонстрировать несколько примеров, как это сделать:
var foo = 3.14,
    bar = foo.toString(10); // '3.14' 
var foo = 3.14,
    bar = foo + ''; // '3.14'
foo += ''; // '3.14'


Я неспроста вызвал метод toString с параметром 10 — он указывает, что число нужно преобразовать в строку в десятичной системе счисления. Соответственно, для случаев, когда вам нужно получить строку в шестнадцатеричной системе счисления, эти шорткаты не помогут.
Иногда для проверки наличия или отсутствия элемента в массиве пишут вот такой код:
if (someArray.indexOf(someElement) >= 0) {
// whatever
}

if (someArray.indexOf(someElement) === -1) {
// whatever
}


Его можно сократить до такого:
if (~someArray.indexOf(someElement)) {
// whatever
}

if (!~someArray.indexOf(someElement)) {
// whatever
}


Чтобы улучшить читабельность этого трюка, проверку можно присвоить переменной с подходящим названием:
var isFound = ~someArray.indexOf(someElement);
if (isFound) {
// whatever
}


Для нормальной работы с arguments в JS не хватает инструментария, поэтому потребность преобразовать arguments к обычному массиву возникает часто. И первое, что удастся загуглить, будет
argsArray = Array.prototype.slice.call(arguments);


Этот вызов можно сократить до
argsArray = [].slice.call(arguments);


Ведь у экземпляра массива тоже есть доступ к прототипу, что сэкономит нам аж 13 символов.
Про этот трюк слышали многие, приведу его для тех, кто не знал:
if (foo !== null || foo !== undefined || foo !== '') {
     bar = foo;
}
bar = foo || '';


Хотелось бы обратить внимание еще раз, что эти примеры мы рассмотрели не для того, чтобы применять их повсеместно, а лишь для того, чтобы лучше понимать возможности некоторых конструкций в JS.

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

Комментариев нет:

Отправить комментарий