Ensure _.isPlainObject returns true for empty objects in older browsers. [closes #283]

Former-commit-id: d01d32b1cbd87d08bc8014d07eaa1842e3118a40
This commit is contained in:
John-David Dalton
2013-05-25 01:08:08 -07:00
parent d15bd23800
commit d28cc15be2
3 changed files with 35 additions and 35 deletions

View File

@@ -1319,14 +1319,11 @@
source = removeFunction(source, 'isNode'); source = removeFunction(source, 'isNode');
source = removeSupportProp(source, 'nodeClass'); source = removeSupportProp(source, 'nodeClass');
// remove `support.nodeClass` from `shimIsPlainObject` // remove `support.nodeClass` from `_.clone` and `shimIsPlainObject`
source = source.replace(matchFunction(source, 'shimIsPlainObject'), function(match) { _.each(['clone', 'shimIsPlainObject'], function(methodName) {
return match.replace(/\(support\.nodeClass[\s\S]+?\)\)/, 'true'); source = source.replace(matchFunction(source, methodName), function(match) {
}); return match.replace(/\s*\|\|\s*\(!support\.nodeClass[\s\S]+?\)\)/, '');
});
// remove `support.nodeClass` from `_.clone`
source = source.replace(matchFunction(source, 'clone'), function(match) {
return match.replace(/\s*\|\|\s*\(!support\.nodeClass[\s\S]+?\)\)/, '');
}); });
// remove `support.nodeClass` from `_.isEqual` // remove `support.nodeClass` from `_.isEqual`

View File

@@ -1026,34 +1026,33 @@
* @returns {Boolean} Returns `true`, if `value` is a plain object, else `false`. * @returns {Boolean} Returns `true`, if `value` is a plain object, else `false`.
*/ */
function shimIsPlainObject(value) { function shimIsPlainObject(value) {
// avoid non-objects and false positives for `arguments` objects var ctor,
var result = false; result;
if (!(value && toString.call(value) == objectClass) || (!support.argsClass && isArguments(value))) {
return result;
}
// check that the constructor is `Object` (i.e. `Object instanceof Object`)
var ctor = value.constructor;
if (isFunction(ctor) ? ctor instanceof ctor : (support.nodeClass || !isNode(value))) { // avoid non Object objects, `arguments` objects, and DOM elements
// IE < 9 iterates inherited properties before own properties. If the first if (!(value && toString.call(value) == objectClass) ||
// iterated property is an object's own property then there are no inherited (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor)) ||
// enumerable properties. (!support.argsClass && isArguments(value)) ||
if (support.ownLast) { (!support.nodeClass && isNode(value))) {
forIn(value, function(value, key, object) { return false;
result = hasOwnProperty.call(object, key);
return false;
});
return result === true;
}
// In most environments an object's own properties are iterated before
// its inherited properties. If the last iterated property is an object's
// own property then there are no inherited enumerable properties.
forIn(value, function(value, key) {
result = key;
});
return result === false || hasOwnProperty.call(value, result);
} }
return result; // IE < 9 iterates inherited properties before own properties. If the first
// iterated property is an object's own property then there are no inherited
// enumerable properties.
if (support.ownLast) {
forIn(value, function(value, key, object) {
result = hasOwnProperty.call(object, key);
return false;
});
return result !== false;
}
// In most environments an object's own properties are iterated before
// its inherited properties. If the last iterated property is an object's
// own property then there are no inherited enumerable properties.
forIn(value, function(value, key) {
result = key;
});
return result === undefined || hasOwnProperty.call(value, result);
} }
/** /**

View File

@@ -1655,12 +1655,16 @@
} }
}); });
test('should return `true` for empty objects', function() {
strictEqual(_.isPlainObject({}), true);
});
test('should return `false` for Object objects without a [[Class]] of "Object"', function() { test('should return `false` for Object objects without a [[Class]] of "Object"', function() {
strictEqual(_.isPlainObject(arguments), false); strictEqual(_.isPlainObject(arguments), false);
strictEqual(_.isPlainObject(Error), false); strictEqual(_.isPlainObject(Error), false);
strictEqual(_.isPlainObject(Math), false); strictEqual(_.isPlainObject(Math), false);
strictEqual(_.isPlainObject(window), false); strictEqual(_.isPlainObject(window), false);
}) });
}()); }());
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/