Начинающий JavaScript ООП против функционала

Я только начинаю исследовать различные стили программирования (ООП, функциональное, процедурное).

Я изучаю JavaScript и начинаю подчеркивать.js и пришли вместе этой небольшой раздел в документации. В документах говорится, что подчеркивание.js может использоваться в объектно-ориентированном или функциональном стиле, и оба они приводят к одному и тому же.

_.map([1, 2, 3], function(n){ return n * 2; });
_([1, 2, 3]).map(function(n){ return n * 2; });

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

5 ответов


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

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

первый тип _.map - это функция _ пространство имен. Это автономная функция, и вы можете вернуть ее или передать другой функции в качестве аргумента.

function compose(f, g) {
  return function(data) {
    return f(g(data));
  }
}

const flatMap = compose(_.flatten, _.map);

невозможно сделать то же самое для второго стиля, потому что экземпляр метода внутренне связан с данными, используемыми для построения объекта. Поэтому я бы сказал, что первая форма больше функциональные.

в любом случае, общий функциональный стиль программирования заключается в том, что данные должны быть окончательным аргументом функции, что облегчает Карри или частично применить предыдущие аргументы. Lodash / fp и ramda адресуйте это, имея следующую подпись для map.

_.map(func, data);

если функция curried, вы можете создать определенные версии функции, только передав первый аргумент.

const double = x => x * 2;
const mapDouble = _.map(double);

mapDouble([1, 2, 3]);
// => [2, 4, 6]

Парадигмы Программирования

объектно-ориентированное программирование (ООП) и функциональное программирование (ФП) являются парадигмами программирования. Грубо говоря, следование парадигме программирования-это написание кода, совместимого с определенным набором правил. Например, организация кода в единицы будет называться ООП, избегание побочных эффектов будет называться FP.

каждая парадигма программирования имеет особенности, однако ваш любимый язык не должен обеспечивать все особенности, чтобы попасть в одну парадигму. На самом деле, ООП может жить без наследование или инкапсуляция, таким образом, мы можем сказать, что JavaScript (JS) является языком ООП с наследованием и без инкапсуляции.

теперь, когда у вас есть немного понимания того, что такое парадигма программирования (надеюсь), давайте быстро рассмотрим самые основы ООП и FP.

Объектно-Ориентированное Программирование

в ООП объект представляет собой коробку, содержащую информация и операции, которые должны относиться к одной и той же концепции. Информация часто известна как" атрибуты", а операции часто известны как"методы". Атрибуты позволяют отслеживать состояние объекта, а методы позволяют управлять состоянием объекта.

в JS вы можете отправить сообщение объекту для выполнения определенного метода. Приведенный ниже код является примером сообщение передает в JS. Он показывает объект" point", который имеет два атрибуты "x" и "y", а также метод под названием "translate". Метод "translate" обновляет координаты "точки" на основе заданного вектора.

point = {
  x: 10, y: 10,
  translate: function (vector) {
    this.x += vector.x;
    this.y += vector.y;
  }
};

point.x; // 10
point.translate({ x: 10, y: 0 });
point.x; // 20

в таком простом случае не так много функций. В ООП код часто разделяется на классы и обычно поддерживает наследование и полиморфизм. Но я не буду вдаваться в подробности, поскольку, боюсь, я уже вышел за рамки вашего вопроса.

Функциональное Программирование

в FP, код представляет собой комбинацию функций. Кроме того, данные неизменны, что приводит к написанию программ без побочных эффектов. В функциональном коде функция не способна изменять внешний мир, а выходное значение зависит только от заданных аргументов. Это позволяет сохранить сильный контроль над потоком программы.

на самом деле JS можно использовать в качестве языка FP, пока вы заботитесь о побочных эффектах, для этого нет встроенного механизма. Следующий код является пример такого стиля программирования. Функция "zipWith" происходит от Хаскелл мире. Он объединяет два списка, используя данную функцию, как это происходит, add(point[i], vector[i]).

zipWith = function (f, as, bs) {
  if (as.length == 0) return [];
  if (bs.length == 0) return [];
  return [f(as[0], bs[0])].concat(
    zipWith(f, as.slice(1), bs.slice(1))
  );
};

add = function (a, b) {
  return a + b;
};

translate = function (point, vector) {
  return zipWith(add, point, vector);
};

point = [10, 10];
point[0]; // 10
point = translate(point, [10, 0]);
point[0]; // 20
это определение очень поверхностно. Например, Haskell, который является чистым функциональным языком, реализует еще много понятий, таких как состав функций, функторы, Карри, монады и т. д... что делает код намного более сжатым и элегантный.

вывод

на самом деле, ООП и FP-это два разных понятия, которые не имеют ничего общего, я бы даже сказал, что сравнивать нечего. Таким образом, я считаю, что то, что вы прочитали, подчеркивает.JS docs-это неправильное использование языка.

вы не должны изучать парадигмы программирования в области этой библиотеки. Действительно, то, как вы пишете код с подчеркиванием.js делает его похожим на ООП и FP, но это только вопрос внешнего вида. Отсюда ничего действительно захватывающего под капотом : -)


обратитесь к Википедии для самостоятельного чтения.


функционал: вы передаете объект функции и делаете вещи

_.map([1, 2, 3], function(n){ return n * 2; });

ООП: вы вызываете функцию на объекте и делаете вещи

_([1, 2, 3]).map(function(n){ return n * 2; });

В обоих примерах [1,2,3] (array) - это объект.

пример ссылки ООП:http://underscorejs.org/#times


строго говоря, оба они ООП. Однако первый метод (_.map) также называется функцией утилиты. Функция является методом _ объект, но оператор не создает новый экземпляр _ конструктор и значение возвращается после вызова метода. Поскольку возвращаемое значение является объектом массива, вы также можете вызвать все методы массивов. Это означает, что это все еще ООП, потому что в JavaScript почти все является объектом.

второй создается новый экземпляр _ объект, который делает методы (методы объекта подчеркивания) цепными, и вы должны использовать value метод получения обернутого значения.

этот абзац по существу означает, что в первом фрагменте не создается объект подчеркивания, а во втором фрагменте объект подчеркивания создается за сценой.

здесь функция ООП/относится к стилистической и не прагматическая перспектива разработчик JavaScript.


и map функционально, и оба кода основаны на concpet, value => value функцией map.

однако, оба также можно увидеть ООП, потому что объект.стиль карты.

Я бы не рекомендовал вам понимать функциональное программирование через подчеркивание.