diff --git a/lodash.src.js b/lodash.src.js index 4bec0ff10..14a9d3eac 100644 --- a/lodash.src.js +++ b/lodash.src.js @@ -828,8 +828,8 @@ }()); /* Native method references for those with the same name as other `lodash` methods. */ - var nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray, - nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate, + var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate, + nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray, nativeIsFinite = context.isFinite, nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys, nativeMax = Math.max, @@ -3419,8 +3419,19 @@ */ function createCtorWrapper(Ctor) { return function() { + // Use a `switch` statement to work with class constructors. + // See https://people.mozilla.org/~jorendorff/es6-draft.html#sec-ecmascript-function-objects-call-thisargument-argumentslist + // for more details. + var args = arguments; + switch (args.length) { + case 0: return new Ctor; + case 1: return new Ctor(args[0]); + case 2: return new Ctor(args[0], args[1]); + case 3: return new Ctor(args[0], args[1], args[2]); + case 4: return new Ctor(args[0], args[1], args[2], args[3]); + } var thisBinding = baseCreate(Ctor.prototype), - result = Ctor.apply(thisBinding, arguments); + result = Ctor.apply(thisBinding, args); // Mimic the constructor's `return` behavior. // See https://es5.github.io/#x13.2.2 for more details. diff --git a/test/test.js b/test/test.js index 0c44d211b..19472c21f 100644 --- a/test/test.js +++ b/test/test.js @@ -1494,7 +1494,7 @@ deepEqual(bound(['b'], 'c'), [object, 'a', ['b'], 'c']); }); - test('should rebind functions', 3, function() { + test('should not rebind functions', 3, function() { var object1 = {}, object2 = {}, object3 = {}; @@ -1508,6 +1508,31 @@ deepEqual(bound3(), [object1, 'b']); }); + test('should not error when calling bound class constructors', 1, function() { + var createCtor = _.attempt(Function, '"use strict";return class A{}'); + if (typeof createCtor == 'function') { + var bound = _.bind(createCtor()), + expected = _.times(5, _.constant(true)); + + var actual = _.times(5, function(index) { + try { + switch (index) { + case 0: return !!(new bound); + case 1: return !!(new bound(1)); + case 2: return !!(new bound(1, 2)); + case 3: return !!(new bound(1, 2, 3)); + case 4: return !!(new bound(1, 2, 3, 4)); + } + } catch(e) {} + }); + + deepEqual(actual, expected); + } + else { + skipTest(); + } + }); + test('should return a wrapped value when chaining', 2, function() { if (!isNpm) { var object = {},