array-iteration.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. var bind = require('../internals/function-bind-context');
  2. var IndexedObject = require('../internals/indexed-object');
  3. var toObject = require('../internals/to-object');
  4. var toLength = require('../internals/to-length');
  5. var arraySpeciesCreate = require('../internals/array-species-create');
  6. var push = [].push;
  7. // `Array.prototype.{ forEach, map, filter, some, every, find, findIndex, filterOut }` methods implementation
  8. var createMethod = function (TYPE) {
  9. var IS_MAP = TYPE == 1;
  10. var IS_FILTER = TYPE == 2;
  11. var IS_SOME = TYPE == 3;
  12. var IS_EVERY = TYPE == 4;
  13. var IS_FIND_INDEX = TYPE == 6;
  14. var IS_FILTER_OUT = TYPE == 7;
  15. var NO_HOLES = TYPE == 5 || IS_FIND_INDEX;
  16. return function ($this, callbackfn, that, specificCreate) {
  17. var O = toObject($this);
  18. var self = IndexedObject(O);
  19. var boundFunction = bind(callbackfn, that, 3);
  20. var length = toLength(self.length);
  21. var index = 0;
  22. var create = specificCreate || arraySpeciesCreate;
  23. var target = IS_MAP ? create($this, length) : IS_FILTER || IS_FILTER_OUT ? create($this, 0) : undefined;
  24. var value, result;
  25. for (;length > index; index++) if (NO_HOLES || index in self) {
  26. value = self[index];
  27. result = boundFunction(value, index, O);
  28. if (TYPE) {
  29. if (IS_MAP) target[index] = result; // map
  30. else if (result) switch (TYPE) {
  31. case 3: return true; // some
  32. case 5: return value; // find
  33. case 6: return index; // findIndex
  34. case 2: push.call(target, value); // filter
  35. } else switch (TYPE) {
  36. case 4: return false; // every
  37. case 7: push.call(target, value); // filterOut
  38. }
  39. }
  40. }
  41. return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : target;
  42. };
  43. };
  44. module.exports = {
  45. // `Array.prototype.forEach` method
  46. // https://tc39.es/ecma262/#sec-array.prototype.foreach
  47. forEach: createMethod(0),
  48. // `Array.prototype.map` method
  49. // https://tc39.es/ecma262/#sec-array.prototype.map
  50. map: createMethod(1),
  51. // `Array.prototype.filter` method
  52. // https://tc39.es/ecma262/#sec-array.prototype.filter
  53. filter: createMethod(2),
  54. // `Array.prototype.some` method
  55. // https://tc39.es/ecma262/#sec-array.prototype.some
  56. some: createMethod(3),
  57. // `Array.prototype.every` method
  58. // https://tc39.es/ecma262/#sec-array.prototype.every
  59. every: createMethod(4),
  60. // `Array.prototype.find` method
  61. // https://tc39.es/ecma262/#sec-array.prototype.find
  62. find: createMethod(5),
  63. // `Array.prototype.findIndex` method
  64. // https://tc39.es/ecma262/#sec-array.prototype.findIndex
  65. findIndex: createMethod(6),
  66. // `Array.prototype.filterOut` method
  67. // https://github.com/tc39/proposal-array-filtering
  68. filterOut: createMethod(7)
  69. };