Javascript функция цепочки без членов цепочки зная друг о друге - PullRequest
0 голосов
/ 01 сентября 2011

Я хочу создать конвейер javascript, такой как powershell, bash (|) или f # (|>). То есть. что-то эквивалентное

getstuff() | sort() | grep("foo") | take(5)

Я видел обсуждение этого на coffeescript форуме, но в конце концов они отложили его, потому что все говорили, что вы можете сделать то же самое с помощью цепочки функций. Но насколько я вижу, для этого требуется getstuff, возвращающий что-то с методом сортировки; метод sort должен возвращать то, что имеет метод grep и т. д. Это довольно ограничительно, поскольку требует, чтобы все потенциальные члены конвейера заранее знали друг о друге. Я знаю, что в JavaScript есть несколько довольно хитрых трюков, и я все еще на уровне 101 - так что это выполнимо

getstuff().sort.().grep().take()

без этого ограничения

Ответы [ 4 ]

2 голосов
/ 01 сентября 2011

Определение объекта для поддержки требуемого вида цепочки функций на самом деле довольно просто:

getStuff = ->
  sort: ->
    # set @stuff...
    this
  grep: (str) ->
    # modify @stuff...
    this
  take: (num) ->
    @stuff[num]

Это все, что вам нужно, чтобы getstuff().sort.().grep('foo').take(5) работал.

2 голосов
/ 01 сентября 2011

это выполнимо

getstuff().sort.().grep().take()

без этого ограничения

номер


Мне нравятся короткие ответы! Можете ли вы предложить каким-либо образом, что-то подобное можно сделать

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

Не продолжать побеждать мертвую лошадь jQuery, но один из лучших способов понять, о чем я говорю, это просто начать копаться в исходном коде ядра jQuery и выяснить, как работает цепочка ,

0 голосов
/ 01 сентября 2011

Вы можете сделать что-то подобное, вернув специальный объект, в котором есть все необходимые методы, но который можно использовать вместо конечного значения.Например, вы можете вернуть экземпляр Array, в котором есть все эти методы.

var getstuff = function () {
    obj = Array.apply(this, arguments);
    obj.take = function (n) {
        return this[n];
    };
    obj.grep = function (regexp) {
        return getstuff.apply(this, Array.prototype.filter.apply(this, [function (item) {
            return item.toString().search(regexp) !== -1;
        }]));
    };
    obj.splice = function () {
        return getstuff.apply(this, Array.prototype.splice.apply(this, arguments));
    }
    return obj;
}

// shows [-8, 1]
console.log(getstuff(3, 1, 2, 'b', -8).sort().grep(/\d+/).splice(0, 2));
// shows 3
var stuff = getstuff(3, 1, 2, 'b', -8).grep(/\d+/);
console.log(stuff.sort()[stuff.length]);

Обратите внимание, что приведенное выше не очень быстрая реализация, но он возвращает массивы специальными методами, сохраняя при этомПрототип global Allay чист, поэтому он не будет мешать другому коду.

Вы можете сделать это быстрее, определив эти специальные методы на Array.prototype, но вы должны быть осторожны с этим ...

Или, если ваш браузер поддерживает подклассы Array, то все, что вам нужно, это надкласс и удобный конструктор, getstuff().

0 голосов
/ 01 сентября 2011

Вы можете делать эти вызовы, не беспокоясь о возвращаемых значениях, используя соответствующие методы, например:

take(5, grep("foo", sort(getstuff())));

Но это не решает проблему каждой функции, требующей передачи значимых для нее данных. Даже JavaScript не такой уж скользкий. Вы можете вызвать метод sort () для изображения (например,), но нет никакого осмысленного способа получения результатов.

...