Procházet zdrojové kódy

LibJS: Add the Object.getOwnPropertySymbols method

Idan Horowitz před 4 roky
rodič
revize
bd9e20ef79

+ 1 - 0
Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h

@@ -137,6 +137,7 @@ namespace JS {
     P(getMonth)                              \
     P(getOwnPropertyDescriptor)              \
     P(getOwnPropertyNames)                   \
+    P(getOwnPropertySymbols)                 \
     P(getPrototypeOf)                        \
     P(getSeconds)                            \
     P(getTime)                               \

+ 17 - 15
Userland/Libraries/LibJS/Runtime/Object.cpp

@@ -307,23 +307,25 @@ MarkedValueList Object::get_own_properties(PropertyKind kind, bool only_enumerab
         return properties;
     }
 
-    for (auto& entry : m_indexed_properties) {
-        auto value_and_attributes = entry.value_and_attributes(const_cast<Object*>(this));
-        if (only_enumerable_properties && !value_and_attributes.attributes.is_enumerable())
-            continue;
+    if (return_type != GetOwnPropertyReturnType::SymbolOnly) {
+        for (auto& entry : m_indexed_properties) {
+            auto value_and_attributes = entry.value_and_attributes(const_cast<Object*>(this));
+            if (only_enumerable_properties && !value_and_attributes.attributes.is_enumerable())
+                continue;
 
-        if (kind == PropertyKind::Key) {
-            properties.append(js_string(vm(), String::number(entry.index())));
-        } else if (kind == PropertyKind::Value) {
-            properties.append(value_and_attributes.value);
-        } else {
-            auto* entry_array = Array::create(global_object());
-            entry_array->define_property(0, js_string(vm(), String::number(entry.index())));
-            entry_array->define_property(1, value_and_attributes.value);
-            properties.append(entry_array);
+            if (kind == PropertyKind::Key) {
+                properties.append(js_string(vm(), String::number(entry.index())));
+            } else if (kind == PropertyKind::Value) {
+                properties.append(value_and_attributes.value);
+            } else {
+                auto* entry_array = Array::create(global_object());
+                entry_array->define_property(0, js_string(vm(), String::number(entry.index())));
+                entry_array->define_property(1, value_and_attributes.value);
+                properties.append(entry_array);
+            }
+            if (vm().exception())
+                return MarkedValueList { heap() };
         }
-        if (vm().exception())
-            return MarkedValueList { heap() };
     }
 
     auto add_property_to_results = [&](auto& property) {

+ 9 - 0
Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp

@@ -33,6 +33,7 @@ void ObjectConstructor::initialize(GlobalObject& global_object)
     define_native_function(vm.names.is, is, 2, attr);
     define_native_function(vm.names.getOwnPropertyDescriptor, get_own_property_descriptor, 2, attr);
     define_native_function(vm.names.getOwnPropertyNames, get_own_property_names, 1, attr);
+    define_native_function(vm.names.getOwnPropertySymbols, get_own_property_symbols, 1, attr);
     define_native_function(vm.names.getPrototypeOf, get_prototype_of, 1, attr);
     define_native_function(vm.names.setPrototypeOf, set_prototype_of, 2, attr);
     define_native_function(vm.names.isExtensible, is_extensible, 1, attr);
@@ -74,6 +75,14 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_names)
     return Array::create_from(global_object, object->get_own_properties(PropertyKind::Key, false, GetOwnPropertyReturnType::StringOnly));
 }
 
+JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_symbols)
+{
+    auto* object = vm.argument(0).to_object(global_object);
+    if (vm.exception())
+        return {};
+    return Array::create_from(global_object, object->get_own_properties(PropertyKind::Key, false, GetOwnPropertyReturnType::SymbolOnly));
+}
+
 JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_prototype_of)
 {
     auto* object = vm.argument(0).to_object(global_object);

+ 1 - 0
Userland/Libraries/LibJS/Runtime/ObjectConstructor.h

@@ -30,6 +30,7 @@ private:
     JS_DECLARE_NATIVE_FUNCTION(is);
     JS_DECLARE_NATIVE_FUNCTION(get_own_property_descriptor);
     JS_DECLARE_NATIVE_FUNCTION(get_own_property_names);
+    JS_DECLARE_NATIVE_FUNCTION(get_own_property_symbols);
     JS_DECLARE_NATIVE_FUNCTION(get_prototype_of);
     JS_DECLARE_NATIVE_FUNCTION(set_prototype_of);
     JS_DECLARE_NATIVE_FUNCTION(is_extensible);

+ 16 - 0
Userland/Libraries/LibJS/Tests/builtins/Object/Object.getOwnPropertySymbols.js

@@ -0,0 +1,16 @@
+test("use with array", () => {
+    let names = Object.getOwnPropertySymbols([1, 2, 3]);
+    console.log(names);
+    expect(names).toEqual([]);
+});
+
+test("use with object", () => {
+    let names = Object.getOwnPropertySymbols({ [Symbol.iterator]: 1, [Symbol.species]: 2 });
+    expect(names).toEqual([Symbol.iterator, Symbol.species]);
+});
+
+test("use with object with string keys", () => {
+    let symbol = Symbol("bar");
+    let names = Object.getOwnPropertySymbols({ foo: 1, [symbol]: 2, baz: 3 });
+    expect(names).toEqual([symbol]);
+});