Как связать функции без использования прототипа? - PullRequest
16 голосов
/ 18 февраля 2012

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

function one(num){
    return num+1;
}

function two(num){
    return num+2;
}

Я могу позвонить им с two(two(one(5)))

Но я бы предпочел использовать (5).one().two().two()

Как мне добиться этого без использования прототипа?

Я пытался понять, как работает цепочка подчеркивания, но их код слишком интенсивен, чтобы понять это

Ответы [ 4 ]

22 голосов
/ 18 февраля 2012

Синтаксис точки зарезервирован для объектов.Так что вы можете сделать что-то вроде

function MyNumber(n) {
    var internal = Number(n);
    this.one = function() {
        internal += 1;
        // here comes the magic that allows chaining:
        return this;
    }
    // this.two analogous
    this.valueOf = function() {
        return internal;
    }
}

new MyNumber(5).one().two().two().valueOf(); // 10

Или вы собираетесь реализовать эти методы на прототипе собственного объекта / функции Number.Это позволило бы (5).one()...

6 голосов
/ 31 августа 2014

Чтобы не вызывать toValue в конце цепочки, как в решении @ Bergi, вы можете использовать функцию с прикрепленными методами.JS автоматически вызовет toValue при попытке преобразовать в него тип примитива.

function MyNumber(n) {
    function x () { }
    x.one = function() { n++; return this; };
    x.valueOf = function() { return n; };
    return x;
}

Затем,

MyNumber(5).one().one()
> 7
4 голосов
/ 18 февраля 2012

Хорошей и общей альтернативой является создание пользовательской функции композиции функции

var go = function(x, fs){
   for(var i=0; i < fs.length; i++){
       x = fs[i](x);
   }
   return x;
}

Вы можете назвать это так:

go(5, [one, two, two])

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

0 голосов
/ 04 июля 2016

Другой альтернативой является использование функции lodash flow .Например:

var five = _.flow(one, two, two)
five(5)

Я предпочитаю назначать новую цепочку переменной.Это дает ему ясное имя и поощряет повторное использование.

Кстати, lodash также помогает в передаче дополнительных аргументов функциям цепочки.Например:

var addFive = _.flow(
   _.partialRight(_.add, 1),
   _.partialRight(_.add, 2),
   _.partialRight(_.add, 2)
)

Существует множество других полезных функций, которые могут помочь в функциональной цепочке, например, частичное , распространение , отражение отрицание и т. Д.

...