From 3fa1ae3bc43045efed263d78754c050fd6cfe000 Mon Sep 17 00:00:00 2001 From: Nik Krimm Date: Wed, 4 May 2016 14:03:17 -0500 Subject: [PATCH] Add _.method as peer to _.property for capturing return values of functions on an Object. Closes #2286: Underscore could use a _.propertyResult. --- test/utility.js | 12 ++++++++++++ underscore.js | 15 +++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/test/utility.js b/test/utility.js index 6a81e8735..0f1a8c4ca 100644 --- a/test/utility.js +++ b/test/utility.js @@ -95,6 +95,18 @@ 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, 'should pass rest of arguments to named method for evaluation'); + assert.equal(_.method(function() { return this.name(); })(stooge), 'moe', 'should apply a function literal passed.'); + assert.equal(_.method(function(a, b, c) { return this.sum(a, b, c); })(stooge, 1, 2, 3), 6, 'should pass 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..7eb3b0675 100644 --- a/underscore.js +++ b/underscore.js @@ -1370,6 +1370,21 @@ _.property = property; + // Generates a function for a given object that returns the passed function's return value. + // Accepts a method name or function literal for value. + // If value is a string, function assumes this string is a method name on the + // referenced object. + _.method = function(value) { + return restArgs(function(obj, args) { + if (obj == null) { return; } + var func = _.isFunction(value) ? value : obj[value]; + if (func) { + return func.apply(obj, args); + } + }); + }; + + // Generates a function for a given object that returns a given property. _.propertyOf = function(obj) { return obj == null ? function(){} : function(key) {