Update vendors.

This commit is contained in:
John-David Dalton
2014-05-16 00:09:35 -07:00
parent 41ac7062f8
commit bfc40498bd
13 changed files with 649 additions and 243 deletions

View File

@@ -3,16 +3,16 @@
module('Arrays');
test('first', function() {
equal(_.first([1,2,3]), 1, 'can pull out the first element of an array');
equal(_.first([1, 2, 3]), 1, 'can pull out the first element of an array');
equal(_([1, 2, 3]).first(), 1, 'can perform OO-style "first()"');
deepEqual(_.first([1, 2, 3], 0), [], 'can pass an index to first');
deepEqual(_.first([1, 2, 3], 2), [1, 2], 'can pass an index to first');
deepEqual(_.first([1, 2, 3], 5), [1, 2, 3], 'can pass an index to first');
var result = (function(){ return _.first(arguments); })(4, 3, 2, 1);
equal(result, 4, 'works on an arguments object.');
result = _.map([[1,2,3],[1,2,3]], _.first);
result = _.map([[1, 2, 3], [1, 2, 3]], _.first);
deepEqual(result, [1, 1], 'works well with _.map');
result = (function() { return _.take([1,2,3], 2); })();
result = (function() { return _.take([1, 2, 3], 2); })();
deepEqual(result, [1, 2], 'aliased as take');
equal(_.first(null), undefined, 'handles nulls');
@@ -26,7 +26,7 @@
deepEqual(_.rest(numbers, 2), [3, 4], 'rest can take an index');
var result = (function(){ return _(arguments).tail(); })(1, 2, 3, 4);
deepEqual(result, [2, 3, 4], 'aliased as tail and works on arguments object');
result = _.map([[1,2,3],[1,2,3]], _.rest);
result = _.map([[1, 2, 3], [1, 2, 3]], _.rest);
deepEqual(_.flatten(result), [2, 3, 2, 3], 'works well with _.map');
result = (function(){ return _(arguments).drop(); })(1, 2, 3, 4);
deepEqual(result, [2, 3, 4], 'aliased as drop and works on arguments object');
@@ -38,18 +38,18 @@
deepEqual(_.initial([1, 2, 3, 4], 6), [], 'initial can take a large index');
var result = (function(){ return _(arguments).initial(); })(1, 2, 3, 4);
deepEqual(result, [1, 2, 3], 'initial works on arguments object');
result = _.map([[1,2,3],[1,2,3]], _.initial);
result = _.map([[1, 2, 3], [1, 2, 3]], _.initial);
deepEqual(_.flatten(result), [1, 2, 1, 2], 'initial works with _.map');
});
test('last', function() {
equal(_.last([1,2,3]), 3, 'can pull out the last element of an array');
equal(_.last([1, 2, 3]), 3, 'can pull out the last element of an array');
deepEqual(_.last([1, 2, 3], 0), [], 'can pass an index to last');
deepEqual(_.last([1, 2, 3], 2), [2, 3], 'can pass an index to last');
deepEqual(_.last([1, 2, 3], 5), [1, 2, 3], 'can pass an index to last');
var result = (function(){ return _(arguments).last(); })(1, 2, 3, 4);
equal(result, 4, 'works on an arguments object');
result = _.map([[1,2,3],[1,2,3]], _.last);
result = _.map([[1, 2, 3], [1, 2, 3]], _.last);
deepEqual(result, [3, 3], 'works well with _.map');
equal(_.last(null), undefined, 'handles nulls');
@@ -64,10 +64,10 @@
test('flatten', function() {
var list = [1, [2], [3, [[[4]]]]];
deepEqual(_.flatten(list), [1,2,3,4], 'can flatten nested arrays');
deepEqual(_.flatten(list, true), [1,2,3,[[[4]]]], 'can shallowly flatten nested arrays');
deepEqual(_.flatten(list), [1, 2, 3, 4], 'can flatten nested arrays');
deepEqual(_.flatten(list, true), [1, 2, 3, [[[4]]]], 'can shallowly flatten nested arrays');
var result = (function(){ return _.flatten(arguments); })(1, [2], [3, [[[4]]]]);
deepEqual(result, [1,2,3,4], 'works on an arguments object');
deepEqual(result, [1, 2, 3, 4], 'works on an arguments object');
list = [[1], [2], [3], [[4]]];
deepEqual(_.flatten(list, true), [1, 2, 3, [4]], 'can shallowly flatten arrays containing only other arrays');
});
@@ -90,7 +90,7 @@
list = [1, 1, 1, 2, 2, 3];
deepEqual(_.uniq(list, true), [1, 2, 3], 'can find the unique values of a sorted array faster');
list = [{name:'moe'}, {name:'curly'}, {name:'larry'}, {name:'curly'}];
list = [{name: 'moe'}, {name: 'curly'}, {name: 'larry'}, {name: 'curly'}];
var iterator = function(value) { return value.name; };
deepEqual(_.map(_.uniq(list, false, iterator), iterator), ['moe', 'curly', 'larry'], 'can find the unique values of an array using a custom iterator');
@@ -161,16 +161,19 @@
test('zip', function() {
var names = ['moe', 'larry', 'curly'], ages = [30, 40, 50], leaders = [true];
var stooges = _.zip(names, ages, leaders);
equal(String(stooges), 'moe,30,true,larry,40,,curly,50,', 'zipped together arrays of different lengths');
deepEqual(_.zip(names, ages, leaders), [
['moe', 30, true],
['larry', 40, undefined],
['curly', 50, undefined]
], 'zipped together arrays of different lengths');
stooges = _.zip(['moe',30, 'stooge 1'],['larry',40, 'stooge 2'],['curly',50, 'stooge 3']);
deepEqual(stooges, [['moe','larry','curly'],[30,40,50], ['stooge 1', 'stooge 2', 'stooge 3']], 'zipped pairs');
var stooges = _.zip(['moe', 30, 'stooge 1'], ['larry', 40, 'stooge 2'], ['curly', 50, 'stooge 3']);
deepEqual(stooges, [['moe', 'larry', 'curly'], [30, 40, 50], ['stooge 1', 'stooge 2', 'stooge 3']], 'zipped pairs');
// In the case of difference lengths of the tuples undefineds
// should be used as placeholder
stooges = _.zip(['moe',30],['larry',40],['curly',50, 'extra data']);
deepEqual(stooges, [['moe','larry','curly'],[30,40,50], [undefined, undefined, 'extra data']], 'zipped pairs with empties');
stooges = _.zip(['moe', 30], ['larry', 40], ['curly', 50, 'extra data']);
deepEqual(stooges, [['moe', 'larry', 'curly'], [30, 40, 50], [undefined, undefined, 'extra data']], 'zipped pairs with empties');
var empty = _.zip([]);
deepEqual(empty, [], 'unzipped empty');

View File

@@ -21,7 +21,7 @@
});
test('select/reject/sortBy', function() {
var numbers = [1,2,3,4,5,6,7,8,9,10];
var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
numbers = _(numbers).chain().select(function(n) {
return n % 2 === 0;
}).reject(function(n) {
@@ -33,7 +33,7 @@
});
test('select/reject/sortBy in functional style', function() {
var numbers = [1,2,3,4,5,6,7,8,9,10];
var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
numbers = _.chain(numbers).select(function(n) {
return n % 2 === 0;
}).reject(function(n) {
@@ -45,7 +45,7 @@
});
test('reverse/concat/unshift/pop/map', function() {
var numbers = [1,2,3,4,5];
var numbers = [1, 2, 3, 4, 5];
numbers = _(numbers).chain()
.reverse()
.concat([5, 5, 5])

View File

@@ -221,10 +221,10 @@
});
test('include', function() {
ok(_.include([1,2,3], 2), 'two is in the array');
ok(!_.include([1,3,9], 2), 'two is not in the array');
ok(_.contains({moe:1, larry:3, curly:9}, 3) === true, '_.include on objects checks their values');
ok(_([1,2,3]).include(2), 'OO-style include');
ok(_.include([1, 2, 3], 2), 'two is in the array');
ok(!_.include([1, 3, 9], 2), 'two is not in the array');
ok(_.contains({moe: 1, larry: 3, curly: 9}, 3) === true, '_.include on objects checks their values');
ok(_([1, 2, 3]).include(2), 'OO-style include');
});
test('invoke', function() {
@@ -280,10 +280,10 @@
result = _.findWhere(list, {b: 4});
deepEqual(result, {a: 1, b: 4});
result = _.findWhere(list, {c:1})
result = _.findWhere(list, {c: 1})
ok(_.isUndefined(result), 'undefined when not found');
result = _.findWhere([], {c:1});
result = _.findWhere([], {c: 1});
ok(_.isUndefined(result), 'undefined when searching empty list');
});
@@ -297,10 +297,15 @@
equal(-Infinity, _.max([]), 'Maximum value of an empty array');
equal(_.max({'a': 'a'}), -Infinity, 'Maximum value of a non-numeric collection');
equal(299999, _.max(_.range(1,300000)), 'Maximum value of a too-big array');
equal(299999, _.max(_.range(1, 300000)), 'Maximum value of a too-big array');
equal(3, _.max([1, 2, 3, 'test']), 'Finds correct max in array starting with num and containing a NaN');
equal(3, _.max(['test', 1, 2, 3]), 'Finds correct max in array starting with NaN');
var a = {x: -Infinity};
var b = {x: -Infinity};
var iterator = function(o){ return o.x; };
equal(_.max([a, b], iterator), a, 'Respects iterator return value of -Infinity');
});
test('min', function() {
@@ -317,10 +322,15 @@
var then = new Date(0);
equal(_.min([now, then]), then);
equal(1, _.min(_.range(1,300000)), 'Minimum value of a too-big array');
equal(1, _.min(_.range(1, 300000)), 'Minimum value of a too-big array');
equal(1, _.min([1, 2, 3, 'test']), 'Finds correct min in array starting with num and containing a NaN');
equal(1, _.min(['test', 1, 2, 3]), 'Finds correct min in array starting with NaN');
var a = {x: Infinity};
var b = {x: Infinity};
var iterator = function(o){ return o.x; };
equal(_.min([a, b], iterator), a, 'Respects iterator return value of Infinity');
});
test('sortBy', function() {
@@ -391,12 +401,12 @@
equal(grouped['3'].length, 1);
var matrix = [
[1,2],
[1,3],
[2,3]
[1, 2],
[1, 3],
[2, 3]
];
deepEqual(_.groupBy(matrix, 0), {1: [[1,2], [1,3]], 2: [[2,3]]})
deepEqual(_.groupBy(matrix, 1), {2: [[1,2]], 3: [[1,3], [2,3]]})
deepEqual(_.groupBy(matrix, 0), {1: [[1, 2], [1, 3]], 2: [[2, 3]]})
deepEqual(_.groupBy(matrix, 1), {2: [[1, 2]], 3: [[1, 3], [2, 3]]})
});
test('indexBy', function() {
@@ -488,7 +498,7 @@
test('toArray', function() {
ok(!_.isArray(arguments), 'arguments object is not an array');
ok(_.isArray(_.toArray(arguments)), 'arguments object converted into array');
var a = [1,2,3];
var a = [1, 2, 3];
ok(_.toArray(a) !== a, 'array is cloned');
deepEqual(_.toArray(a), [1, 2, 3], 'cloned array contains same elements');
@@ -522,13 +532,16 @@
test('partition', function() {
var list = [0, 1, 2, 3, 4, 5];
deepEqual(_.partition(list, function(x) { return x < 4; }), [[0,1,2,3],[4,5]], 'handles bool return values');
deepEqual(_.partition(list, function(x) { return x & 1; }), [[1,3,5],[0,2,4]], 'handles 0 and 1 return values');
deepEqual(_.partition(list, function(x) { return x - 3; }), [[0,1,2,4,5],[3]], 'handles other numeric return values');
deepEqual(_.partition(list, function(x) { return x > 1 ? null : true; }), [[0,1],[2,3,4,5]], 'handles null return values');
deepEqual(_.partition(list, function(x) { if(x < 2) return true; }), [[0,1],[2,3,4,5]], 'handles undefined return values');
deepEqual(_.partition(list, function(x) { return x < 4; }), [[0, 1, 2, 3], [4, 5]], 'handles bool return values');
deepEqual(_.partition(list, function(x) { return x & 1; }), [[1, 3, 5], [0, 2, 4]], 'handles 0 and 1 return values');
deepEqual(_.partition(list, function(x) { return x - 3; }), [[0, 1, 2, 4, 5], [3]], 'handles other numeric return values');
deepEqual(_.partition(list, function(x) { return x > 1 ? null : true; }), [[0, 1], [2, 3, 4, 5]], 'handles null return values');
deepEqual(_.partition(list, function(x) { if(x < 2) return true; }), [[0, 1], [2, 3, 4, 5]], 'handles undefined return values');
deepEqual(_.partition({a: 1, b: 2, c: 3}, function(x) { return x > 1; }), [[2, 3], [1]], 'handles objects');
deepEqual(_.partition(list, function(x, index) { return index % 2; }), [[1, 3, 5], [0, 2, 4]], 'can reference the array index');
deepEqual(_.partition(list, function(x, index, arr) { return x === arr.length - 1; }), [[5], [0, 1, 2, 3, 4]], 'can reference the collection');
// Default iterator
deepEqual(_.partition([1, false, true, '']), [[1, true], [false, '']], 'Default iterator');
deepEqual(_.partition([{x: 1}, {x: 0}, {x: 1}], 'x'), [[{x: 1}, {x: 1}], [{x: 0}]], 'Takes a string');

View File

@@ -38,6 +38,8 @@
equal(newBoundf.hello, undefined, 'function should not be bound to the context, to comply with ECMAScript 5');
equal(Boundf().hello, 'moe curly', "When called without the new operator, it's OK to be bound to the context");
ok(newBoundf instanceof F, 'a bound instance is an instance of the original function');
raises(function() { _.bind('notafunction'); }, TypeError, 'throws an error when binding to a non-function');
});
test('partial', function() {
@@ -98,6 +100,17 @@
var fastO = _.memoize(o);
equal(o('toString'), 'toString', 'checks hasOwnProperty');
equal(fastO('toString'), 'toString', 'checks hasOwnProperty');
// Expose the cache.
var upper = _.memoize(function(s) {
return s.toUpperCase();
});
equal(upper('foo'), 'FOO');
equal(upper('bar'), 'BAR');
deepEqual(upper.cache, {foo: 'FOO', bar: 'BAR'});
upper.cache = {foo: 'BAR', bar: 'FOO'};
equal(upper('foo'), 'BAR');
equal(upper('bar'), 'FOO');
});
asyncTest('delay', 2, function() {
@@ -298,6 +311,29 @@
}, 200);
});
asyncTest('throttle re-entrant', 2, function() {
var sequence = [
['b1', 'b2'],
['c1', 'c2']
];
var value = '';
var throttledAppend;
var append = function(arg){
value += this + arg;
var args = sequence.pop()
if (args) {
throttledAppend.call(args[0], args[1]);
}
};
throttledAppend = _.throttle(append, 32);
throttledAppend.call('a1', 'a2');
equal(value, 'a1a2');
_.delay(function(){
equal(value, 'a1a2c1c2b1b2', 'append was throttled successfully');
start();
}, 100);
});
asyncTest('debounce', 1, function() {
var counter = 0;
var incr = function(){ counter++; };
@@ -353,7 +389,29 @@
equal(counter, 2, 'incr was debounced successfully');
start();
_.now = origNowFunc;
},200);
}, 200);
});
asyncTest('debounce re-entrant', 2, function() {
var sequence = [
['b1', 'b2']
];
var value = '';
var debouncedAppend;
var append = function(arg){
value += this + arg;
var args = sequence.pop()
if (args) {
debouncedAppend.call(args[0], args[1]);
}
};
debouncedAppend = _.debounce(append, 32);
debouncedAppend.call('a1', 'a2');
equal(value, '');
_.delay(function(){
equal(value, 'a1a2b1b2', 'append was debounced successfully');
start();
}, 100);
});
test('once', function() {

View File

@@ -44,22 +44,25 @@
test('extend', function() {
var result;
equal(_.extend({}, {a:'b'}).a, 'b', 'can extend an object with the attributes of another');
equal(_.extend({a:'x'}, {a:'b'}).a, 'b', 'properties in source override destination');
equal(_.extend({x:'x'}, {a:'b'}).x, 'x', "properties not in source don't get overriden");
result = _.extend({x:'x'}, {a:'a'}, {b:'b'});
ok(_.isEqual(result, {x:'x', a:'a', b:'b'}), 'can extend from multiple source objects');
result = _.extend({x:'x'}, {a:'a', x:2}, {a:'b'});
ok(_.isEqual(result, {x:2, a:'b'}), 'extending from multiple source objects last property trumps');
equal(_.extend({}, {a: 'b'}).a, 'b', 'can extend an object with the attributes of another');
equal(_.extend({a: 'x'}, {a: 'b'}).a, 'b', 'properties in source override destination');
equal(_.extend({x: 'x'}, {a: 'b'}).x, 'x', "properties not in source don't get overriden");
result = _.extend({x: 'x'}, {a: 'a'}, {b: 'b'});
ok(_.isEqual(result, {x: 'x', a: 'a', b: 'b'}), 'can extend from multiple source objects');
result = _.extend({x: 'x'}, {a: 'a', x: 2}, {a: 'b'});
ok(_.isEqual(result, {x: 2, a: 'b'}), 'extending from multiple source objects last property trumps');
result = _.extend({}, {a: void 0, b: null});
deepEqual(_.keys(result), ['a', 'b'], 'extend copies undefined values');
try {
result = {};
_.extend(result, null, undefined, {a:1});
_.extend(result, null, undefined, {a: 1});
} catch(ex) {}
equal(result.a, 1, 'should not error on `null` or `undefined` sources');
strictEqual(_.extend(null, {a: 1}), null, 'extending null results in null');
strictEqual(_.extend(undefined, {a: 1}), undefined, 'extending undefined results in undefined');
});
test('pick', function() {
@@ -129,10 +132,13 @@
try {
options = {};
_.defaults(options, null, undefined, {a:1});
_.defaults(options, null, undefined, {a: 1});
} catch(ex) {}
equal(options.a, 1, 'should not error on `null` or `undefined` sources');
strictEqual(_.defaults(null, {a: 1}), null, 'result is null if destination is null');
strictEqual(_.defaults(undefined, {a: 1}), undefined, 'result is undefined if destination is undefined');
});
test('clone', function() {
@@ -350,7 +356,7 @@
// More circular objects #767.
a = {everything: 'is checked', but: 'this', is: 'not'};
a.but = a;
b = {everything: 'is checked', but: {that:'object'}, is: 'not'};
b = {everything: 'is checked', but: {that: 'object'}, is: 'not'};
ok(!_.isEqual(a, b), 'Comparison of circular references with non-circular object references are not equal');
// Cyclic Structures.
@@ -453,7 +459,7 @@
ok(!_.isArguments(_.isArguments), 'a function is not an arguments object');
ok(_.isArguments(args), 'but the arguments object is an arguments object');
ok(!_.isArguments(_.toArray(args)), 'but not when it\'s converted into an array');
ok(!_.isArguments([1,2,3]), 'and not vanilla arrays.');
ok(!_.isArguments([1, 2, 3]), 'and not vanilla arrays.');
ok(_.isArguments(iArguments), 'even from another frame');
});
@@ -596,7 +602,7 @@
equal(intercepted, 1, 'passes tapped object to interceptor');
equal(returned, 1, 'returns tapped object');
returned = _([1,2,3]).chain().
returned = _([1, 2, 3]).chain().
map(function(n){ return n * 2; }).
max().
tap(interceptor).
@@ -614,6 +620,8 @@
var child = {};
child.prototype = obj;
ok(_.has(child, "foo") == false, "has() does not check the prototype chain for a property.");
strictEqual(_.has(null, 'foo'), false, 'has() returns false for null');
strictEqual(_.has(undefined, 'foo'), false, 'has() returns false for undefined');
});
test("matches", function() {

View File

@@ -67,11 +67,11 @@
test('times', function() {
var vals = [];
_.times(3, function (i) { vals.push(i); });
ok(_.isEqual(vals, [0,1,2]), 'is 0 indexed');
ok(_.isEqual(vals, [0, 1, 2]), 'is 0 indexed');
//
vals = [];
_(3).times(function(i) { vals.push(i); });
ok(_.isEqual(vals, [0,1,2]), 'works as a wrapper');
ok(_.isEqual(vals, [0, 1, 2]), 'works as a wrapper');
// collects return values
ok(_.isEqual([0, 1, 2], _.times(3, function(i) { return i; })), 'collects return values');

View File

@@ -232,7 +232,7 @@
} else {
_.each(obj, function(value, index, list) {
computed = iterator ? iterator.call(context, value, index, list) : value;
if (computed > lastComputed) {
if (computed > lastComputed || (computed === -Infinity && result === -Infinity)) {
result = value;
lastComputed = computed;
}
@@ -255,7 +255,7 @@
} else {
_.each(obj, function(value, index, list) {
computed = iterator ? iterator.call(context, value, index, list) : value;
if (computed < lastComputed) {
if (computed < lastComputed || (computed === Infinity && result === Infinity)) {
result = value;
lastComputed = computed;
}
@@ -326,7 +326,7 @@
iterator = lookupIterator(iterator, context);
_.each(obj, function(value, index) {
var key = iterator(value, index, obj);
behavior(result, key, value);
behavior(result, value, key);
});
return result;
};
@@ -334,20 +334,20 @@
// Groups the object's values by a criterion. Pass either a string attribute
// to group by, or a function that returns the criterion.
_.groupBy = group(function(result, key, value) {
_.groupBy = group(function(result, value, key) {
_.has(result, key) ? result[key].push(value) : result[key] = [value];
});
// Indexes the object's values by a criterion, similar to `groupBy`, but for
// when you know that your index values will be unique.
_.indexBy = group(function(result, key, value) {
_.indexBy = group(function(result, value, key) {
result[key] = value;
});
// Counts instances of an object that group by a certain criterion. Pass
// either a string attribute to count by, or a function that returns the
// criterion.
_.countBy = group(function(result, key) {
_.countBy = group(function(result, value, key) {
_.has(result, key) ? result[key]++ : result[key] = 1;
});
@@ -453,8 +453,8 @@
_.partition = function(obj, predicate, context) {
predicate = lookupIterator(predicate, context);
var pass = [], fail = [];
_.each(obj, function(elem) {
(predicate(elem) ? pass : fail).push(elem);
_.each(obj, function(value, key, obj) {
(predicate(value, key, obj) ? pass : fail).push(value);
});
return [pass, fail];
};
@@ -600,7 +600,7 @@
_.bind = function(func, context) {
var args, bound;
if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
if (!_.isFunction(func)) throw new TypeError;
if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');
args = slice.call(arguments, 2);
return bound = function() {
if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
@@ -641,12 +641,15 @@
// Memoize an expensive function by storing its results.
_.memoize = function(func, hasher) {
var memo = {};
hasher || (hasher = _.identity);
return function() {
if (!hasher) hasher = _.identity;
var memoize = function() {
var cache = memoize.cache;
var key = hasher.apply(this, arguments);
return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
if (!_.has(cache, key)) cache[key] = func.apply(this, arguments);
return cache[key];
};
memoize.cache = {};
return memoize;
};
// Delays a function for the given number of milliseconds, and then calls
@@ -676,7 +679,7 @@
previous = options.leading === false ? 0 : _.now();
timeout = null;
result = func.apply(context, args);
context = args = null;
if (!timeout) context = args = null;
};
return function() {
var now = _.now();
@@ -689,7 +692,7 @@
timeout = null;
previous = now;
result = func.apply(context, args);
context = args = null;
if (!timeout) context = args = null;
} else if (!timeout && options.trailing !== false) {
timeout = setTimeout(later, remaining);
}
@@ -713,7 +716,7 @@
timeout = null;
if (!immediate) {
result = func.apply(context, args);
context = args = null;
if (!timeout) context = args = null;
}
}
};
@@ -723,9 +726,7 @@
args = arguments;
timestamp = _.now();
var callNow = immediate && !timeout;
if (!timeout) {
timeout = setTimeout(later, wait);
}
if (!timeout) timeout = setTimeout(later, wait);
if (callNow) {
result = func.apply(context, args);
context = args = null;
@@ -841,11 +842,10 @@
// Extend a given object with all the properties in passed-in object(s).
_.extend = function(obj) {
if (!_.isObject(obj)) return obj;
_.each(slice.call(arguments, 1), function(source) {
if (source) {
for (var prop in source) {
obj[prop] = source[prop];
}
for (var prop in source) {
obj[prop] = source[prop];
}
});
return obj;
@@ -883,11 +883,10 @@
// Fill in a given object with default properties.
_.defaults = function(obj) {
if (!_.isObject(obj)) return obj;
_.each(slice.call(arguments, 1), function(source) {
if (source) {
for (var prop in source) {
if (obj[prop] === void 0) obj[prop] = source[prop];
}
for (var prop in source) {
if (obj[prop] === void 0) obj[prop] = source[prop];
}
});
return obj;
@@ -1040,7 +1039,7 @@
// there isn't any inspectable "Arguments" type.
if (!_.isArguments(arguments)) {
_.isArguments = function(obj) {
return !!(obj && _.has(obj, 'callee'));
return _.has(obj, 'callee');
};
}
@@ -1079,7 +1078,7 @@
// Shortcut function for checking if an object has a given property directly
// on itself (in other words, not on a prototype).
_.has = function(obj, key) {
return hasOwnProperty.call(obj, key);
return obj != null && hasOwnProperty.call(obj, key);
};
// Utility Functions