123456789101112131415161718192021222324252627282930313233343536373839404142 |
- define(['./_setup', './isFunction', './_has'], function (_setup, isFunction, _has) {
- // Internal helper to create a simple lookup structure.
- // `collectNonEnumProps` used to depend on `_.contains`, but this led to
- // circular imports. `emulatedSet` is a one-off solution that only works for
- // arrays of strings.
- function emulatedSet(keys) {
- var hash = {};
- for (var l = keys.length, i = 0; i < l; ++i) hash[keys[i]] = true;
- return {
- contains: function(key) { return hash[key] === true; },
- push: function(key) {
- hash[key] = true;
- return keys.push(key);
- }
- };
- }
- // Internal helper. Checks `keys` for the presence of keys in IE < 9 that won't
- // be iterated by `for key in ...` and thus missed. Extends `keys` in place if
- // needed.
- function collectNonEnumProps(obj, keys) {
- keys = emulatedSet(keys);
- var nonEnumIdx = _setup.nonEnumerableProps.length;
- var constructor = obj.constructor;
- var proto = isFunction(constructor) && constructor.prototype || _setup.ObjProto;
- // Constructor is a special case.
- var prop = 'constructor';
- if (_has(obj, prop) && !keys.contains(prop)) keys.push(prop);
- while (nonEnumIdx--) {
- prop = _setup.nonEnumerableProps[nonEnumIdx];
- if (prop in obj && obj[prop] !== proto[prop] && !keys.contains(prop)) {
- keys.push(prop);
- }
- }
- }
- return collectNonEnumProps;
- });
|