Ensure _.bind works with ES6 class constructors. [closes #1193]

This commit is contained in:
jdalton
2015-05-08 09:49:54 -07:00
parent 542dd67892
commit a61bde5b78
2 changed files with 40 additions and 4 deletions

View File

@@ -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.

View File

@@ -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 = {},