Анализируй и властвуй

  • воскресенье, 22 апреля 2018 г. в 09:21:00

Вчера стало интерено, как работает функция .get() из библиотеки Lodash? А именно получение значения через такой путь a.b[0].c.d. Заглянул в библиотеку Lodash, в метод .get().

Данный метод подключает вспомогательные методы, с помощью которых осуществляется реализация самого .get(). На этот один метод, происходит подключение как минимум 10 дополнительных файлов (методов). Размер самой библиотеки — 70 кб. При подключении lodash/get8 кб. (хотя на самом деле, сам файл с методом .get() весит не более 800 байт).

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

Во-первых, это уменьшает размер вашего бандла. Во-вторых, этот подход (декларативный) считается верным и желательно не подключать всю библиотеку, ради 1-2 методов.


_10
import get from 'lodash/get';

Я хотел посмотреть как работает .get(), но понял, что мне придется изучать кучу других вспомогательных методов. В итоге, я поставил себе задачу написать такой же метод и исключительно в целях практики, а не плодить «yet another cool method» (YACM).


_15
function get(obj, path) {
_15
var keys = path.split('.');
_15
var value = obj;
_15
var arrKey, key, i = 0;
_15
while (value && Object.keys(value).indexOf(keys[i] && keys[i].replace(/\[(.*)\]/, '')) >= 0) {
_15
key = keys[i].replace(/\[(.*)\]/, '');
_15
value = value[key];
_15
arrKey = keys[i++].match(/\[(.*)\]/);
_15
if (Array.isArray(value) && arrKey) {
_15
key = parseInt(arrKey[1]);
_15
value = value[key];
_15
}
_15
}
_15
return value;
_15
}

Да, этот код можно было оптимизировать или написать решение намного лучше. Я это уже понял, когда нашёл это решение.

Этот метод тоже можно немного оптимизировать. К примеру, поместив в один replace все эти три регулярки, вместо вызова трёх. Однако, он всё равно выглядит гораздо симпатичнее моего метода.

Я уверен, что мой метод не пройдёт и 20% тестов. Но, как я сказал ранее, моей задачей было реализовать этот метод самому и добиться хоть какого-нибудь рабочего результата.

Какой вывод?

  1. Интересуйтесь тем, как работает та или иная библиотека, которой вы часто пользуетесь.
  2. Попробуйте сделать то же самое, только своими знаниями. Сравнивайте с наиболее грамотным решением.
  3. Не выкладывайте это решение в сеть. Нет! Если вы написали то же самое, но только хуже, это не значит, что этим будут пользоваться другие. Вот вам живой пример: https://github.com/RobinMalfait/fastget. Очень кривая имитация метода .get(). Данный метод возвращает то значение, которое вы ему передаете. :genius-meme: (и даже есть тесты)

Как это работает и какой от этого смысл?

Анализ ошибок — одна из самых важных частей при изучении чего-либо. Разрабатывая «своё решение», старайтесь не смотреть на готовый код. Попробуйте понять, как примерно работает функция и напишите свою. Сравните с готовым решением и делайте выводы. Вероятней всего, какие-то участки кода можно было написать лучше. Именно анализ своего и чужого кода, дает хороший опыт.

#анализ#lodash#библиотека#декларативный подход