31 Дек


2017

Javascript полезности. ES5. Флэнеган (6 издание)

Я не самый большой фанат js, мне нравится его простота, но то огромное количество методов (которые зачастую делают весьма похожие вещи) присущие в браузерных реализациях ES меня немного приводит в шок. Я также не могу сказать что хорошо знаю нюансы язык, от части потому, что мало практики написания программ на нем. Также я не в восторге от прототипированного наследования. Однако по большому счету это единственный язык который активно юзается на стороне браузерного клиента ;3 Поэтому выбирать не приходится. В данной статье представлены заинтересовавшие меня методы/решения/нюансы а также best practices о которых не знал лично я. Для других, возможно, все это весьма очевидно и не представляет особого интереса.

1. Тернарный оператор ?: (единственный в js) [105 стр]

Лаконичная запись if else, лично я такого раньше не встречал, а поскольку мне нравится подобный синтаксический сахар то беру на вооружение :

x = 1
1
x > 0 ? 'Yes ofc' : 'Noe ;('
"Yes ofc"

работает это так (любое булианское выражение возвращающее True/False) ? операция если True : операция если False

2. Пустое тело цикла [122 стр]

Во первых стоит отметить что в цикле for любое из трех выражений может быть опущено, однако при этом все раво необходим указывать, таким образом реализация бесконечного цикла может выглядить так: for(::)

Во 2 стоит отметить необзательность объявления тела цикла {}. Однако интерпритатор может принять следующую строку за циклом как тело, воизбижание этих проблем используется точка с запятой после цикла, а также зачастую указывается комментарий для явного указания того что цикл. Например копирование элементов массива можно произвести так:

var o = {x:1, y:2, z:3}
var a = []; i = 0;
for(a[i++] in o) /* empty cycle's body */;
a
>>> (3) ["x", "y", "z"]

3. Исключения [129 стр]

Если честно я не помню почему поставил закладку в книге на этом мест, нооо раз первоначальный 'Я' посчитал это важным то кто я такой чтобы с этим спорить?

try {
    //пытаемся сделать-что-нибудь
}
catch (e) {
    // если возникло исключение
}
finally {
    // инструкции в этом блоке будут выполнены внезависимости от того
    // было исключение или нет
}

// возбуждение исключения
throw new Error("Ошибочка");

3. Атрибуты свойств [157 стр]

Атрибуты свойств; value - значение свойства, writable - доступность для записи, enumerable - доступность для перечисления, configurable - доступность натройки.

Для того чтобы знать есть атрибуты, или нет используется следующий метод (вернет либо хеш таблицу из атрибутов либо undefined);

Object.getOwnPropertyDescriptor({}, "x");

Для создание/изменения атрибутов используется метод Object.defineProperty(объект, свойство, {атрибуты})

Object.defineProperty(o, "x", { value : 1,
    writable: true,
    enumerable: false,
    configurable: true});

Если свойства не указаны они получат значение false или undefined.

Переорпделение метода extend() позволяющего копировать свойства из 1 объекта в другой.
Object.defineProperty(Object.prototype,
 "extend", // Оп­ре­де­ля­ет­ся Object.prototype.extend
 {
   writable: true,
   enumerable: false, // Сде­лать не­пе­ре­чис­ли­мым
   configurable: true,
   value: function(o) { // Зна­че­ни­ем свой­ст­ва яв­ля­ет­ся дан­ная функ­ция
   // По­лу­чить все соб­ст­вен­ные свой­ст­ва, да­же не­пе­ре­чис­ли­мые
   var names = Object.getOwnPropertyNames(o);
   // Обой­ти их в цик­ле
   for(var i = 0; i < names.length; i++) {
   // Про­пус­тить свой­ст­ва, уже имею­щие­ся в дан­ном объ­ек­те
   if (names[i] in this) continue;
   // По­лу­чить де­ск­рип­тор свой­ст­ва из o
   var desc = Object.getOwnPropertyDescriptor(o,names[i]);
   // Соз­дать с его по­мо­щью свой­ст­во в дан­ном объ­ек­те
   Object.defineProperty(this, names[i], desc);
 }
}
});

4. Массивы [168 стр]

Интересное решение, не уверен что где-то еще такое видел.

a = [1,2,3,4,5]; // Соз­дать мас­сив с пя­тью эле­мен­та­ми.
a.length = 3; // те­перь мас­сив a со­дер­жит эле­мен­ты [1,2,3].
a.length = 0; // Уда­лит все эле­мен­ты. a - пус­той мас­сив [].
a.length = 5; // Дли­на рав­на 5, но эле­мен­ты от­сут­ст­ву­ют, по­доб­но Array(5)

Массивы имеют также методы push(значение) pop(), думаю не стоит их объяснять, а также shift() unshift() убирающий начальный элемент со сдвигом и добовляющий соответственно.

В es5 появился метод forEach позволяющий обойти каждый элемент массива 

var data = [0, 1, 2, 3, 4]
var sum = 0
data.forEach(function(x) {
	sum += x
})
sum
>>10
Методы для работы с массивами

concat() - объеденяет массив с указанным в качестве аргумента значением, либо с другим массивомвозвращает в качстве значения новый массив

slice() - как можно догадаться из названия возвращает срез

splice() - метод выполняющий вставку и удалние

var a = [1,2,3,4,5,6,7,8];
a.splice(4); // Вер­нет [5,6,7,8]; a = [1,2,3,4]
a.splice(1,2); // Вер­нет [2,3]; a = [1,4]
a.splice(1,1); // Вер­нет [4]; a = [1]

push() pop() - думаю не нуждаются в описании

shift() unshift() - тоже самое что и push pop только значение берут/кладут в начале массива

следующие методы появились в es5, первым аргументов они принимают функцию оперирущую с элементами массива

map() - делает тоже самое что и forEach, с той лишь разницей, что возвращает массив не изменяя текущего

filter() - функция должна возвращать true/false , результатом операции будет новый массив удовлетворяющий описанному условию

every() some() - по сути являются ванторами всеобщности и существования, первый проверяет все ли элементы удовлетворяют условию, 2-ой метод проверяет выполняет ли условию хотя бы 1 элемент. Возвращают true/false соответственно

reduce() - объеденяет элементы массива (делает свертку) и возвращает единственное значение, 1 аргумент функции внутри метода - результат предыдущей операции, а 2 текущее значение массива)

reduceRight() - тоже самое толко свертка начинается с последнего элемента

indexOf(), lastIndexOf() - возвращают индекс первого/последнего элемента переданного в качестве аргумента, в случае если элемент не найден вернет -1 (здорово если в массиве есть отрицательные индексы, -1 будет всьма информативным)

5. Функции, arguments [195 стр]

Интересной особенностью мне показалось тут то что функция вне зависимости от количества формальных параметров может принимать безграничное их количество, которые будут записаны в массив arguments локальной области видимости.

Не столь важные вещи, который меня удивили.

1. В JavaScript нет integer. нет, он там как бы представлен своим типом number, вот только number это по сути float, который принимает максимальное число 2 ^ 53 - 1, мне это показалось страным, за ним следует infinity.

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