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

Дата: 22.04.2018 в 12:21, Категория: JavaScript
  • 681
  • 0
Анализируй и властвуй

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

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

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

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

import get from 'lodash/get';

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

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

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

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

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

# Какой вывод?

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

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

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