Как цеплять функции без использования прототипа? - программирование
Подтвердить что ты не робот

Как цеплять функции без использования прототипа?

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

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

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

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

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

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

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

4b9b3361

Ответ 1

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

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()...

Ответ 2

Чтобы избежать необходимости называть 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

Ответ 3

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

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

Вы можете называть это следующим образом:

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

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

Ответ 4

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

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

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

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

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

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