diff --git a/test/utility.js b/test/utility.js index 6a81e8735..9c7a013e7 100644 --- a/test/utility.js +++ b/test/utility.js @@ -95,6 +95,22 @@ assert.equal(undefPropertyOf('curly'), void 0, 'should return undefined when obj is undefined'); }); + QUnit.test('method', function(assert) { + var stooge = {name: function () { + return 'moe'; + }, sum: function(a,b,c) { + return a + b + c + }}; + assert.equal(_.method('name')(stooge), 'moe', 'should return the results of calling the method with the given name'); + assert.equal(_.method('sum')(stooge, 1, 2, 3), 6, 'passes rest of arguments to named method for evaluation'); + assert.equal(_.method(function () { return this.name(); })(stooge), 'moe', 'attempts to apply a function literal passed.'); + assert.equal(_.method(function (a,b,c) { return this.sum(a,b,c); })(stooge, 1, 2, 3), 6, 'passes arguments when applying a function literal.'); + assert.equal(_.method('macerena')(stooge), void 0, 'should return undefined for non-existant method name on defined object'); + assert.equal(_.method('name')(null), void 0, 'should return undefined for null object'); + assert.equal(_.method()(stooge), void 0, 'should return undefined for undefined method name on existing object'); + assert.equal(_.method()(void 0), void 0, 'should return undefined for undefined method name on undefined object'); + }); + QUnit.test('random', function(assert) { var array = _.range(1000); var min = Math.pow(2, 31); diff --git a/underscore.js b/underscore.js index 4a0cf6e73..cec28bcc2 100644 --- a/underscore.js +++ b/underscore.js @@ -1370,6 +1370,24 @@ _.property = property; + // Generates a function for a given object that returns the passed function's return value. + // Accepts a string or function literal for value. + // If value is a string, function assumes (and verifies) this string is a method name on the + // referenced object. + _.method = function (value) { + var isFunction = this.isFunction, + rest = this.rest, + func; + + return function(obj) { + if (obj == null) { return; } + func = isFunction(value) ? value : obj[value]; + if (func) { + return func.apply(obj, rest(arguments)); + } + } + } + // Generates a function for a given object that returns a given property. _.propertyOf = function(obj) { return obj == null ? function(){} : function(key) {