static bool IsConcatSpreadable(Isolate* isolate, Handle<Object> obj) {
HandleScope handle_scope(isolate);
if (!obj->IsSpecObject()) return false;
- if (obj->IsJSArray()) return true;
if (FLAG_harmony_arrays) {
Handle<Symbol> key(isolate->factory()->is_concat_spreadable_symbol());
Handle<Object> value;
MaybeHandle<Object> maybeValue =
i::Runtime::GetObjectProperty(isolate, obj, key);
if (maybeValue.ToHandle(&value)) {
- return value->BooleanValue();
+ if (!value->IsUndefined()) {
+ return value->BooleanValue();
+ }
}
}
- return false;
+ return obj->IsJSArray();
}
(function testConcatArraySubclass() {
"use strict";
+ // If @@isConcatSpreadable is not used, the value of IsArray(O)
+ // is used to determine the spreadable property.
+ class A extends Array {}
+ var obj = [].concat(new A(1, 2, 3), new A(4, 5, 6), new A(7, 8, 9));
+ assertEquals(9, obj.length);
+ for (var i = 0; i < obj.length; ++i) {
+ assertEquals(i + 1, obj[i]);
+ }
+
// TODO(caitp): when concat is called on instances of classes which extend
// Array, they should:
//
})();
+(function testConcatArraySubclassOptOut() {
+ "use strict";
+ class A extends Array {
+ get [Symbol.isConcatSpreadable]() { return false; }
+ }
+ var obj = [].concat(new A(1, 2, 3), new A(4, 5, 6), new A(7, 8, 9));
+ assertEquals(3, obj.length);
+ assertEquals(3, obj[0].length);
+ assertEquals(3, obj[1].length);
+ assertEquals(3, obj[2].length);
+})();
+
+
(function testConcatNonArray() {
"use strict";
class NonArray {