Chain methods by reference instead of property.

This commit is contained in:
John-David Dalton
2015-01-04 15:47:33 -06:00
parent bfe833c132
commit 11de155432
2 changed files with 56 additions and 27 deletions

View File

@@ -2697,11 +2697,10 @@
while (++index < length) { while (++index < length) {
var args = [result], var args = [result],
action = actions[index], action = actions[index];
object = action.object;
push.apply(args, action.args); push.apply(args, action.args);
result = object[action.name].apply(object, args); result = action.func.apply(action.thisArg, args);
} }
return result; return result;
} }
@@ -10209,23 +10208,25 @@
chain = options.chain; chain = options.chain;
} }
while (++index < length) { while (++index < length) {
var methodName = methodNames[index]; var methodName = methodNames[index],
object[methodName] = source[methodName]; func = source[methodName];
object[methodName] = func;
if (isFunc) { if (isFunc) {
object.prototype[methodName] = (function(methodName) { object.prototype[methodName] = (function(func) {
return function() { return function() {
var chainAll = this.__chain__; var chainAll = this.__chain__;
if (chain || chainAll) { if (chain || chainAll) {
var result = object(this.__wrapped__); var result = object(this.__wrapped__);
(result.__actions__ = baseSlice(this.__actions__)).push({ 'args': arguments, 'object': object, 'name': methodName }); (result.__actions__ = baseSlice(this.__actions__)).push({ 'func': func, 'args': arguments, 'thisArg': object });
result.__chain__ = chainAll; result.__chain__ = chainAll;
return result; return result;
} }
var args = [this.value()]; var args = [this.value()];
push.apply(args, arguments); push.apply(args, arguments);
return object[methodName].apply(object, args); return func.apply(object, args);
}; };
}(methodName)); }(func));
} }
} }
return object; return object;
@@ -10678,10 +10679,10 @@
lodash.prototype.sample = function(n) { lodash.prototype.sample = function(n) {
if (!this.__chain__ && n == null) { if (!this.__chain__ && n == null) {
return lodash.sample(this.value()); return sample(this.value());
} }
return this.thru(function(value) { return this.thru(function(value) {
return lodash.sample(value, n); return sample(value, n);
}); });
}; };
@@ -10835,7 +10836,7 @@
if (!retUnwrapped && (isHybrid || result.actions)) { if (!retUnwrapped && (isHybrid || result.actions)) {
var actions = result.actions || (result.actions = []); var actions = result.actions || (result.actions = []);
actions.push({ 'args': [interceptor], 'object': lodash, 'name': 'thru' }); actions.push({ 'func': thru, 'args': [interceptor], 'thisArg': lodash });
} }
return new LodashWrapper(result, chainAll); return new LodashWrapper(result, chainAll);
} }

View File

@@ -294,11 +294,10 @@
while (++index < length) { while (++index < length) {
var args = [result], var args = [result],
action = actions[index], action = actions[index];
object = action.object;
push.apply(args, action.args); push.apply(args, action.args);
result = object[action.name].apply(object, args); result = action.func.apply(action.thisArg, args);
} }
return result; return result;
} }
@@ -806,7 +805,7 @@
if (!isNpm && lodashBizarro) { if (!isNpm && lodashBizarro) {
var actual = _.map(values, function(value) { var actual = _.map(values, function(value) {
var wrapped = _(lodashBizarro(value)), var wrapped = _(lodashBizarro(value)),
unwrapped = getUnwrappedValue(wrapped); unwrapped = wrapped.value();
return wrapped instanceof _ && return wrapped instanceof _ &&
(unwrapped === value || (_.isNaN(unwrapped) && _.isNaN(value))); (unwrapped === value || (_.isNaN(unwrapped) && _.isNaN(value)));
@@ -9056,15 +9055,15 @@
return getUnwrappedValue(this); return getUnwrappedValue(this);
}; };
var value = ['a'], var array = ['a'],
source = { 'a': function(array) { return array[0]; }, 'b': 'B' }; source = { 'a': function(array) { return array[0]; }, 'b': 'B' };
test('should mixin `source` methods into lodash', 4, function() { test('should mixin `source` methods into lodash', 4, function() {
if (!isNpm) { if (!isNpm) {
_.mixin(source); _.mixin(source);
strictEqual(_.a(value), 'a'); strictEqual(_.a(array), 'a');
strictEqual(getUnwrappedValue(_(value).a()), 'a'); strictEqual(_(array).a().value(), 'a');
delete _.a; delete _.a;
delete _.prototype.a; delete _.prototype.a;
@@ -9080,11 +9079,27 @@
} }
}); });
test('should mixin chaining methods by reference', 2, function() {
if (!isNpm) {
_.mixin(source);
_.a = _.constant('b');
strictEqual(_.a(array), 'b');
strictEqual(_(array).a().value(), 'a');
delete _.a;
delete _.prototype.a;
}
else {
skipTest(2);
}
});
test('should use `this` as the default `object` value', 3, function() { test('should use `this` as the default `object` value', 3, function() {
var object = _.create(_); var object = _.create(_);
object.mixin(source); object.mixin(source);
strictEqual(object.a(value), 'a'); strictEqual(object.a(array), 'a');
ok(!('a' in _)); ok(!('a' in _));
ok(!('a' in _.prototype)); ok(!('a' in _.prototype));
@@ -9098,7 +9113,7 @@
test('should accept an `object` argument', 1, function() { test('should accept an `object` argument', 1, function() {
var object = {}; var object = {};
_.mixin(object, source); _.mixin(object, source);
strictEqual(object.a(value), 'a'); strictEqual(object.a(array), 'a');
}); });
test('should return `object`', 2, function() { test('should return `object`', 2, function() {
@@ -9110,7 +9125,7 @@
test('should work with a function for `object`', 2, function() { test('should work with a function for `object`', 2, function() {
_.mixin(Wrapper, source); _.mixin(Wrapper, source);
var wrapped = Wrapper(value), var wrapped = Wrapper(array),
actual = wrapped.a(); actual = wrapped.a();
strictEqual(actual.value(), 'a'); strictEqual(actual.value(), 'a');
@@ -9142,7 +9157,7 @@
} else { } else {
_.mixin(func, source, options); _.mixin(func, source, options);
} }
var wrapped = func(value), var wrapped = func(array),
actual = wrapped.a(); actual = wrapped.a();
if (options === true || (options && options.chain)) { if (options === true || (options && options.chain)) {
@@ -9222,12 +9237,10 @@
test('should produce methods that work in a lazy chain sequence', 1, function() { test('should produce methods that work in a lazy chain sequence', 1, function() {
if (!isNpm) { if (!isNpm) {
var array = [1, 2, 1, 3], var predicate = function(value) { return value > 1; };
predicate = function(value) { return value > 1; };
_.mixin({ 'a': _.countBy, 'b': _.filter }); _.mixin({ 'a': _.countBy, 'b': _.filter });
var actual = _(array).a(_.identity).map(String).b(predicate).take().value(); var actual = _([1, 2, 1, 3]).a(_.identity).map(String).b(predicate).take().value();
deepEqual(actual, ['2']); deepEqual(actual, ['2']);
delete _.a; delete _.a;
@@ -11284,6 +11297,21 @@
} }
}); });
test('should use a stored reference to `_.sample` when chaining', 2, function() {
if (!isNpm) {
var sample = _.sample;
_.sample = _.noop;
var wrapped = _(array);
notStrictEqual(wrapped.sample(), undefined);
notStrictEqual(wrapped.sample(2).value(), undefined);
_.sample = sample;
}
else {
skipTest(2);
}
});
_.each({ _.each({
'literal': 'abc', 'literal': 'abc',
'object': Object('abc') 'object': Object('abc')