晴明的博客园 GitHub      CodePen      CodeWars     

[question] Decorator

#

function Decorator(options) {
  if (!options) {
    options = {};
  }
  this.before = options.before;
  this.after = options.after;
}

Decorator.prototype.decorate = function decorate(fn) {
  var decArgs = Array.prototype.slice.call(arguments, 1), self = this;
  return function() {
    var input = Array.prototype.slice.call(arguments, 0);
    if(typeof self.before == 'function') {
      input = self.before.apply(null, decArgs.concat(input)) || input;
    }
    input = fn.apply(self, input);
    if(typeof self.after == 'function') {
      input = self.after.apply(null, decArgs.concat(input)) || input;
    }
    return input;
  }
};

 

#

 

function sum() {
  return Array.prototype.reduce.call(arguments, function(sum, value) {
    return sum + value;
  }, 0);
}

function filter(min, max) {
  return Array.prototype.slice.call(arguments, 2).filter(function(value) {
    return value >= min && value <= max;
  });
}


function filterNoNumbers() {
  return Array.prototype.filter.call(arguments, function(value) {
    return typeof value === 'number' && value === value && value !== Number.POSITIVE_INFINITY && value !== Number.NEGATIVE_INFINITY;
  });
}

function round(decimals) {
  if (arguments.length === 2) {
    return arguments[1].toFixed(decimals);
  } else {
    return Array.prototype.splice.call(arguments, 1).map(function(value) {
      return value.toFixed(decimals);
    });
  }
}

var nullDecorator = new Decorator();
var testNullDecorator = nullDecorator.decorate(function() {
  return true;
});

Test.assertEquals(testNullDecorator(), true, 'A null decorator does nothing');

var filterDecorator = new Decorator({
  before : filter
});

var decoratedSum = filterDecorator.decorate(sum, 1, 9);

Test.assertSimilar(decoratedSum(-3, 1, 0, 4, 8, 9, 12), 22, 'sum values that are between the minimum and maximum');


var filterNoNumbersDecorator = new Decorator({
  before : filterNoNumbers
});

decoratedSum = filterNoNumbersDecorator.decorate(decoratedSum);

Test.assertEquals(decoratedSum(-3, 1, 0, 4, NaN, 8, '27', 9, 12), 22, 'sum values that are numbers and are between the minimum and maximum');

var roundDecorator = new Decorator({
  after: round
});

decoratedSum = roundDecorator.decorate(decoratedSum, 2);

Test.assertEquals(decoratedSum(-3, 1.016, 0, 4, NaN, 8.041, '27', 9, 12), "22.06", 'sum isRounded to two decimals');

decoratedSum = nullDecorator.decorate(decoratedSum, 2);

Test.assertEquals(decoratedSum(-3, 1.016, 0, 4, NaN, 8.041, '27', 9, 12), "22.06", 'A null decorator does nothing');

var decoratedSum2 = filterNoNumbersDecorator.decorate(sum);
decoratedSum2 = roundDecorator.decorate(decoratedSum2, 2);
decoratedSum2 = filterDecorator.decorate(decoratedSum2, 1, 9);

Test.assertEquals(decoratedSum2(-3, 1.016, 0, 4, NaN, 8.041, '27', 9, 12), "22.06", 'The order in which decorators are applied does not alter the result.');

 

posted @ 2016-04-29 15:05  晴明桑  阅读(130)  评论(0)    收藏  举报