_methodFingerprint.js 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738
  1. import getLength from './_getLength.js';
  2. import isFunction from './isFunction.js';
  3. import allKeys from './allKeys.js';
  4. // Since the regular `Object.prototype.toString` type tests don't work for
  5. // some types in IE 11, we use a fingerprinting heuristic instead, based
  6. // on the methods. It's not great, but it's the best we got.
  7. // The fingerprint method lists are defined below.
  8. export function ie11fingerprint(methods) {
  9. var length = getLength(methods);
  10. return function(obj) {
  11. if (obj == null) return false;
  12. // `Map`, `WeakMap` and `Set` have no enumerable keys.
  13. var keys = allKeys(obj);
  14. if (getLength(keys)) return false;
  15. for (var i = 0; i < length; i++) {
  16. if (!isFunction(obj[methods[i]])) return false;
  17. }
  18. // If we are testing against `WeakMap`, we need to ensure that
  19. // `obj` doesn't have a `forEach` method in order to distinguish
  20. // it from a regular `Map`.
  21. return methods !== weakMapMethods || !isFunction(obj[forEachName]);
  22. };
  23. }
  24. // In the interest of compact minification, we write
  25. // each string in the fingerprints only once.
  26. var forEachName = 'forEach',
  27. hasName = 'has',
  28. commonInit = ['clear', 'delete'],
  29. mapTail = ['get', hasName, 'set'];
  30. // `Map`, `WeakMap` and `Set` each have slightly different
  31. // combinations of the above sublists.
  32. export var mapMethods = commonInit.concat(forEachName, mapTail),
  33. weakMapMethods = commonInit.concat(mapTail),
  34. setMethods = ['add'].concat(commonInit, forEachName, hasName);