两种调用方法:

(function(root) {
  function stream(data) {
    if (!(this instanceof stream)) {
      return new stream(data);
    }
    this.data = data;
  }
  stream.unique = function(array, callback) {
    var result = [];
    array.forEach(item => {
      item = callback ? callback(item) : item;
      if (result.indexOf(item) === -1) {
        result.push(item);
      }
    });
    return result;
  };
  stream.functions = function(obj) {
    var result = [];
    var key;
    for (key in obj) {
      result.push(key);
    }
    return result;
  };
  stream.each = function(array, callback) {
    for (var i = 0, length = array.length; i < length; i++) {
      callback.call(array, array[i]);
    }
  };
  stream.mixin = function(obj) {
    stream.each(stream.functions(obj), function(name) {
      stream.prototype[name] = function() {
        var args = [this.data];
        [].push.apply(args, arguments);
        return stream[name].apply(this, args);
      };
    });
  };
  stream.mixin(stream);
  root.stream = stream;
})(this);
var array = [1, 2, 2, 3, "A", "a"];
console.log(
  stream.unique(array, function(item) {
    return typeof item === "string" ? item.toLocaleLowerCase() : item;
  })
);
console.log(
  stream(array).unique(function(item) {
    return typeof item === "string" ? item.toLocaleLowerCase() : item;
  })
);

JavaScript 流式编程:

(function(root) {
  function stream(data) {
    if (!(this instanceof stream)) {
      return new stream(data);
    }
    this.data = data;
  }
  stream.unique = function(array, callback) {
    var result = [];
    array.forEach(item => {
      item = callback ? callback(item) : item;
      if (result.indexOf(item) === -1) {
        result.push(item);
      }
    });
    return result;
  };
  stream.functions = function(obj) {
    var result = [];
    var key;
    for (key in obj) {
      result.push(key);
    }
    return result;
  };
  stream.each = function(array, callback) {
    for (var i = 0, length = array.length; i < length; i++) {
      callback.call(array, array[i]);
    }
  };
  stream.mixin = function(obj) {
    stream.each(stream.functions(obj), function(name) {
      stream.prototype[name] = function() {
        var args = [this.data];
        [].push.apply(args, arguments);
        return stream.result(this, stream[name].apply(this, args));
      };
    });
  };
  stream.chain = function(obj) {
    var instance = stream(obj);
    instance._chain = true;
    return instance;
  };
  stream.prototype.values = function() {
    return this.data;
  };
  stream.suffix = function(array) {
    array = JSON.parse(JSON.stringify(array))
    array.push("suffix");
    return array;
  };
  stream.result = function(instance, obj) {
    if (instance._chain) {
      instance.data = obj;
      return instance;
    }
    return obj;
  };
  stream.mixin(stream);
  root.stream = stream;
})(this);
var array = [1, 2, 2, 3, "A", "a"];
console.log(
  stream.unique(array, function(item) {
    return typeof item === "string" ? item.toLocaleLowerCase() : item;
  })
);
console.log(stream.suffix(array));
console.log(
  stream(array)
    .chain()
    .unique(function(item) {
      return typeof item === "string" ? item.toLocaleLowerCase() : item;
    })
    .suffix()
    .values()
);