3 var iteratorSymbol = require('es6-symbol').iterator
4 , isArguments = require('../../function/is-arguments')
5 , isFunction = require('../../function/is-function')
6 , toPosInt = require('../../number/to-pos-integer')
7 , callable = require('../../object/valid-callable')
8 , validValue = require('../../object/valid-value')
9 , isString = require('../../string/is-string')
11 , isArray = Array.isArray, call = Function.prototype.call
12 , desc = { configurable: true, enumerable: true, writable: true, value: null }
13 , defineProperty = Object.defineProperty;
15 module.exports = function (arrayLike/*, mapFn, thisArg*/) {
16 var mapFn = arguments[1], thisArg = arguments[2], Constructor, i, j, arr, l, code, iterator
17 , result, getIterator, value;
19 arrayLike = Object(validValue(arrayLike));
21 if (mapFn != null) callable(mapFn);
22 if (!this || (this === Array) || !isFunction(this)) {
23 // Result: Plain array
25 if (isArguments(arrayLike)) {
28 if (l !== 1) return Array.apply(null, arrayLike);
30 arr[0] = arrayLike[0];
33 if (isArray(arrayLike)) {
35 arr = new Array(l = arrayLike.length);
36 for (i = 0; i < l; ++i) arr[i] = arrayLike[i];
42 // Result: Non plain array
46 if (!isArray(arrayLike)) {
47 if ((getIterator = arrayLike[iteratorSymbol]) !== undefined) {
49 iterator = callable(getIterator).call(arrayLike);
50 if (Constructor) arr = new Constructor();
51 result = iterator.next();
53 while (!result.done) {
54 value = mapFn ? call.call(mapFn, thisArg, result.value, i) : result.value;
59 defineProperty(arr, i, desc);
61 result = iterator.next();
65 } else if (isString(arrayLike)) {
68 if (Constructor) arr = new Constructor();
69 for (i = 0, j = 0; i < l; ++i) {
72 code = value.charCodeAt(0);
73 if ((code >= 0xD800) && (code <= 0xDBFF)) value += arrayLike[++i];
75 value = mapFn ? call.call(mapFn, thisArg, value, j) : value;
80 defineProperty(arr, j, desc);
87 if (l === undefined) {
88 // Source: array or array-like
89 l = toPosInt(arrayLike.length);
90 if (Constructor) arr = new Constructor(l);
91 for (i = 0; i < l; ++i) {
92 value = mapFn ? call.call(mapFn, thisArg, arrayLike[i], i) : arrayLike[i];
97 defineProperty(arr, i, desc);