1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
/*
* Copyright (C) 2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
function of(/* items... */)
{
"use strict";
var length = arguments.length;
// TODO: Need isConstructor(this) instead of typeof "function" check.
var array = typeof this === 'function' ? new this(length) : new @Array(length);
for (var k = 0; k < length; ++k)
@putByValDirect(array, k, arguments[k]);
array.length = length;
return array;
}
function from(items /*, mapFn, thisArg */)
{
"use strict";
var thisObj = this;
var mapFn = arguments.length > 1 ? arguments[1] : @undefined;
var thisArg;
if (mapFn !== @undefined) {
if (typeof mapFn !== "function")
throw new @TypeError("Array.from requires that the second argument, when provided, be a function");
if (arguments.length > 2)
thisArg = arguments[2];
}
if (items == null)
throw new @TypeError("Array.from requires an array-like object - not null or undefined");
var iteratorMethod = items[@symbolIterator];
if (iteratorMethod != null) {
if (typeof iteratorMethod !== "function")
throw new @TypeError("Array.from requires that the property of the first argument, items[Symbol.iterator], when exists, be a function");
// TODO: Need isConstructor(thisObj) instead of typeof "function" check.
var result = (typeof thisObj === "function") ? @Object(new thisObj()) : [];
var k = 0;
var iterator = iteratorMethod.@call(items);
// Since for-of loop once more looks up the @@iterator property of a given iterable,
// it could be observable if the user defines a getter for @@iterator.
// To avoid this situation, we define a wrapper object that @@iterator just returns a given iterator.
var wrapper = {
[@symbolIterator]() {
return iterator;
}
};
for (var value of wrapper) {
if (mapFn)
@putByValDirect(result, k, thisArg === @undefined ? mapFn(value, k) : mapFn.@call(thisArg, value, k));
else
@putByValDirect(result, k, value);
k += 1;
}
result.length = k;
return result;
}
var arrayLike = @Object(items);
var arrayLikeLength = @toLength(arrayLike.length);
// TODO: Need isConstructor(thisObj) instead of typeof "function" check.
var result = (typeof thisObj === "function") ? @Object(new thisObj(arrayLikeLength)) : new @Array(arrayLikeLength);
var k = 0;
while (k < arrayLikeLength) {
var value = arrayLike[k];
if (mapFn)
@putByValDirect(result, k, thisArg === @undefined ? mapFn(value, k) : mapFn.@call(thisArg, value, k));
else
@putByValDirect(result, k, value);
k += 1;
}
result.length = arrayLikeLength;
return result;
}
|