Как цеплять функции без использования прототипа?
У меня есть множество полезных функций, которые я собрал за всю свою жизнь.
function one(num){
return num+1;
}
function two(num){
return num+2;
}
Я могу назвать их с помощью two(two(one(5)))
Но я бы предпочел использовать (5).one().two().two()
Как я могу достичь этого без использования прототипа?
Я пытался увидеть, как работает цепочка подчеркивания, но их код слишком интенсивный, чтобы понять его.
Ответы
Ответ 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)
)
Есть много других полезных функций, которые помогают в функциональной цепочке, например, частичном, распространении, перевороте, отрицании и т.д.