From 9c9731e08e3876afae912bf09acf816430fdeb39 Mon Sep 17 00:00:00 2001 From: Adam Craven Date: Sun, 20 Feb 2011 21:03:52 +0100 Subject: [PATCH 1/5] Added support for ECMAScript 5 native `bind` method if available. Additional unit test to cover multiple argument binds. --- test/functions.js | 4 ++++ underscore.js | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/test/functions.js b/test/functions.js index 230ebea9a..f74bc7294 100644 --- a/test/functions.js +++ b/test/functions.js @@ -20,6 +20,10 @@ $(document).ready(function() { var func = _.bind(func, this, 'curly'); equals(func(), 'hello: curly', 'the function was completely applied in advance'); + + var func = function(salutation, firstname, lastname) { return salutation + ': ' + firstname + ' ' + lastname }; + func = _.bind(func, this, 'hello', 'moe', 'curly'); + equals(func(), 'hello: moe curly', 'the function was partially applied in advance and can accept multiple arguments'); }); test("functions: bindAll", function() { diff --git a/underscore.js b/underscore.js index 5aaaca372..854175858 100644 --- a/underscore.js +++ b/underscore.js @@ -21,7 +21,7 @@ var breaker = {}; // Save bytes in the minified (but not gzipped) version: - var ArrayProto = Array.prototype, ObjProto = Object.prototype; + var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; // Create quick reference variables for speed access to core prototypes. var slice = ArrayProto.slice, @@ -42,7 +42,8 @@ nativeIndexOf = ArrayProto.indexOf, nativeLastIndexOf = ArrayProto.lastIndexOf, nativeIsArray = Array.isArray, - nativeKeys = Object.keys; + nativeKeys = Object.keys, + nativeBind = FuncProto.bind; // Create a safe reference to the Underscore object for use below. var _ = function(obj) { return new wrapper(obj); }; @@ -408,6 +409,7 @@ // optionally). Binding with arguments is also known as `curry`. _.bind = function(func, obj) { var args = slice.call(arguments, 2); + if(nativeBind && func.bind === nativeBind) return FuncProto.bind.apply(func, slice.call(arguments, 1)); return function() { return func.apply(obj || {}, args.concat(slice.call(arguments))); }; From ebde2daa4a73bb0570e59ce3423e3e0bff96aff0 Mon Sep 17 00:00:00 2001 From: Adam Craven Date: Sun, 20 Feb 2011 21:07:14 +0100 Subject: [PATCH 2/5] Updated 'bind' documentation to reflect native support. --- underscore.js | 1 + 1 file changed, 1 insertion(+) diff --git a/underscore.js b/underscore.js index 854175858..d0200efe5 100644 --- a/underscore.js +++ b/underscore.js @@ -407,6 +407,7 @@ // Create a function bound to a given object (assigning `this`, and arguments, // optionally). Binding with arguments is also known as `curry`. + // Delegates to **ECMAScript 5**'s native `Object.bind` if available. _.bind = function(func, obj) { var args = slice.call(arguments, 2); if(nativeBind && func.bind === nativeBind) return FuncProto.bind.apply(func, slice.call(arguments, 1)); From 468160204dc7dc8772202b505ea6327f00419c5e Mon Sep 17 00:00:00 2001 From: Adam Craven Date: Sun, 20 Feb 2011 21:07:14 +0100 Subject: [PATCH 3/5] Updated 'bind' documentation to reflect native support. --- underscore.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/underscore.js b/underscore.js index d0200efe5..6b5a0b06e 100644 --- a/underscore.js +++ b/underscore.js @@ -407,7 +407,7 @@ // Create a function bound to a given object (assigning `this`, and arguments, // optionally). Binding with arguments is also known as `curry`. - // Delegates to **ECMAScript 5**'s native `Object.bind` if available. + // Delegates to **ECMAScript 5**'s native `Function.bind` if available. _.bind = function(func, obj) { var args = slice.call(arguments, 2); if(nativeBind && func.bind === nativeBind) return FuncProto.bind.apply(func, slice.call(arguments, 1)); From b65d647de8405d314268092a9086a25771d575f2 Mon Sep 17 00:00:00 2001 From: Adam Craven Date: Sun, 20 Feb 2011 22:24:29 +0100 Subject: [PATCH 4/5] updated bind method to stop un-needed variable assignment when using native method. --- underscore.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/underscore.js b/underscore.js index 6b5a0b06e..54b9dcc98 100644 --- a/underscore.js +++ b/underscore.js @@ -409,8 +409,8 @@ // optionally). Binding with arguments is also known as `curry`. // Delegates to **ECMAScript 5**'s native `Function.bind` if available. _.bind = function(func, obj) { - var args = slice.call(arguments, 2); if(nativeBind && func.bind === nativeBind) return FuncProto.bind.apply(func, slice.call(arguments, 1)); + var args = slice.call(arguments, 2); return function() { return func.apply(obj || {}, args.concat(slice.call(arguments))); }; From 095400d094aadac0f86e84a41fe894adfe331881 Mon Sep 17 00:00:00 2001 From: Adam Craven Date: Tue, 22 Feb 2011 13:43:39 +0100 Subject: [PATCH 5/5] Use existing alias for function bind. --- underscore.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/underscore.js b/underscore.js index 54b9dcc98..0bad089a4 100644 --- a/underscore.js +++ b/underscore.js @@ -409,7 +409,7 @@ // optionally). Binding with arguments is also known as `curry`. // Delegates to **ECMAScript 5**'s native `Function.bind` if available. _.bind = function(func, obj) { - if(nativeBind && func.bind === nativeBind) return FuncProto.bind.apply(func, slice.call(arguments, 1)); + if(nativeBind && func.bind === nativeBind) return func.bind.apply(func, slice.call(arguments, 1)); var args = slice.call(arguments, 2); return function() { return func.apply(obj || {}, args.concat(slice.call(arguments)));