shim.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. 'use strict';
  2. var iteratorSymbol = require('es6-symbol').iterator
  3. , isArguments = require('../../function/is-arguments')
  4. , isFunction = require('../../function/is-function')
  5. , toPosInt = require('../../number/to-pos-integer')
  6. , callable = require('../../object/valid-callable')
  7. , validValue = require('../../object/valid-value')
  8. , isString = require('../../string/is-string')
  9. , isArray = Array.isArray, call = Function.prototype.call
  10. , desc = { configurable: true, enumerable: true, writable: true, value: null }
  11. , defineProperty = Object.defineProperty;
  12. module.exports = function (arrayLike/*, mapFn, thisArg*/) {
  13. var mapFn = arguments[1], thisArg = arguments[2], Constructor, i, j, arr, l, code, iterator
  14. , result, getIterator, value;
  15. arrayLike = Object(validValue(arrayLike));
  16. if (mapFn != null) callable(mapFn);
  17. if (!this || (this === Array) || !isFunction(this)) {
  18. // Result: Plain array
  19. if (!mapFn) {
  20. if (isArguments(arrayLike)) {
  21. // Source: Arguments
  22. l = arrayLike.length;
  23. if (l !== 1) return Array.apply(null, arrayLike);
  24. arr = new Array(1);
  25. arr[0] = arrayLike[0];
  26. return arr;
  27. }
  28. if (isArray(arrayLike)) {
  29. // Source: Array
  30. arr = new Array(l = arrayLike.length);
  31. for (i = 0; i < l; ++i) arr[i] = arrayLike[i];
  32. return arr;
  33. }
  34. }
  35. arr = [];
  36. } else {
  37. // Result: Non plain array
  38. Constructor = this;
  39. }
  40. if (!isArray(arrayLike)) {
  41. if ((getIterator = arrayLike[iteratorSymbol]) !== undefined) {
  42. // Source: Iterator
  43. iterator = callable(getIterator).call(arrayLike);
  44. if (Constructor) arr = new Constructor();
  45. result = iterator.next();
  46. i = 0;
  47. while (!result.done) {
  48. value = mapFn ? call.call(mapFn, thisArg, result.value, i) : result.value;
  49. if (!Constructor) {
  50. arr[i] = value;
  51. } else {
  52. desc.value = value;
  53. defineProperty(arr, i, desc);
  54. }
  55. result = iterator.next();
  56. ++i;
  57. }
  58. l = i;
  59. } else if (isString(arrayLike)) {
  60. // Source: String
  61. l = arrayLike.length;
  62. if (Constructor) arr = new Constructor();
  63. for (i = 0, j = 0; i < l; ++i) {
  64. value = arrayLike[i];
  65. if ((i + 1) < l) {
  66. code = value.charCodeAt(0);
  67. if ((code >= 0xD800) && (code <= 0xDBFF)) value += arrayLike[++i];
  68. }
  69. value = mapFn ? call.call(mapFn, thisArg, value, j) : value;
  70. if (!Constructor) {
  71. arr[j] = value;
  72. } else {
  73. desc.value = value;
  74. defineProperty(arr, j, desc);
  75. }
  76. ++j;
  77. }
  78. l = j;
  79. }
  80. }
  81. if (l === undefined) {
  82. // Source: array or array-like
  83. l = toPosInt(arrayLike.length);
  84. if (Constructor) arr = new Constructor(l);
  85. for (i = 0; i < l; ++i) {
  86. value = mapFn ? call.call(mapFn, thisArg, arrayLike[i], i) : arrayLike[i];
  87. if (!Constructor) {
  88. arr[i] = value;
  89. } else {
  90. desc.value = value;
  91. defineProperty(arr, i, desc);
  92. }
  93. }
  94. }
  95. if (Constructor) {
  96. desc.value = null;
  97. arr.length = l;
  98. }
  99. return arr;
  100. };