diff --git a/Libraries/LibJS/Runtime/ObjectConstructor.cpp b/Libraries/LibJS/Runtime/ObjectConstructor.cpp index 906b96bc12..36296ea6e5 100644 --- a/Libraries/LibJS/Runtime/ObjectConstructor.cpp +++ b/Libraries/LibJS/Runtime/ObjectConstructor.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include namespace JS { @@ -35,6 +36,7 @@ ObjectConstructor::ObjectConstructor() { put("prototype", interpreter().object_prototype()); + put_native_function("getOwnPropertyNames", get_own_property_names); put_native_function("getPrototypeOf", get_prototype_of); put_native_function("setPrototypeOf", set_prototype_of); } @@ -48,6 +50,24 @@ Value ObjectConstructor::call(Interpreter& interpreter) return interpreter.heap().allocate(); } +Value ObjectConstructor::get_own_property_names(Interpreter& interpreter) +{ + if (interpreter.call_frame().arguments.size() < 1) + return {}; + auto* object = interpreter.call_frame().arguments[0].to_object(interpreter.heap()); + if (interpreter.exception()) + return {}; + auto* result = interpreter.heap().allocate(); + if (object->is_array()) { + auto* array = static_cast(object); + for (i32 i = 0; i < array->length(); ++i) + result->push(js_string(interpreter.heap(), String::number(i))); + } + for (auto& it : object->own_properties()) + result->push(js_string(interpreter.heap(), it.key)); + return result; +} + Value ObjectConstructor::get_prototype_of(Interpreter& interpreter) { if (interpreter.call_frame().arguments.size() < 1) diff --git a/Libraries/LibJS/Runtime/ObjectConstructor.h b/Libraries/LibJS/Runtime/ObjectConstructor.h index 2569f827a2..21430772ab 100644 --- a/Libraries/LibJS/Runtime/ObjectConstructor.h +++ b/Libraries/LibJS/Runtime/ObjectConstructor.h @@ -40,6 +40,7 @@ public: private: virtual const char* class_name() const override { return "ObjectConstructor"; } + static Value get_own_property_names(Interpreter&); static Value get_prototype_of(Interpreter&); static Value set_prototype_of(Interpreter&); }; diff --git a/Libraries/LibJS/Tests/Object.getOwnPropertyNames.js b/Libraries/LibJS/Tests/Object.getOwnPropertyNames.js new file mode 100644 index 0000000000..a9673c03cf --- /dev/null +++ b/Libraries/LibJS/Tests/Object.getOwnPropertyNames.js @@ -0,0 +1,15 @@ +function assert(x) { if (!x) throw 1; } + +try { + var names = Object.getOwnPropertyNames([1, 2, 3]); + + assert(names.length === 4); + assert(names[0] === '0'); + assert(names[1] === '1'); + assert(names[2] === '2'); + assert(names[3] === 'length'); + + console.log("PASS"); +} catch (e) { + console.log("FAIL: " + e); +}