Extract Hidden Keys with Object.getOwnPropertySymbols
JavaScript Symbols are unique primitive values frequently used to
create pseudo-private or collision-resistant property keys on objects.
Because standard enumeration methods like Object.keys() and
for...in loops ignore Symbol properties, these keys are
often referred to as “hidden.” This article explains why Symbols are
excluded from conventional object inspection and demonstrates how the
built-in Object.getOwnPropertySymbols() method locates and
extracts them.
Why Symbol Keys Are “Hidden”
In JavaScript, object property keys can be either strings or Symbols. When you assign a Symbol as a key, JavaScript purposely excludes it from common iteration mechanisms to prevent accidental overwrites, name collisions, and unintended serializations.
The following operations automatically ignore Symbol properties: *
for...in loops * Object.keys() *
Object.values() * Object.entries() *
Object.getOwnPropertyNames() *
JSON.stringify()
Because these mechanisms skip Symbols, they effectively act as hidden metadata on the object.
How Object.getOwnPropertySymbols Works
Object.getOwnPropertySymbols() is a static method
introduced in ECMAScript 2015 (ES6). It inspects a target object’s own
property registry and returns an array containing all Symbol properties
directly attached to that object.
It does not traverse the prototype chain; it only returns Symbols defined directly on the specified instance.
Syntax
Object.getOwnPropertySymbols(obj)- Parameter:
obj— The object whose own Symbol keys you want to retrieve. - Return value: An array of all Symbol properties
found directly on the given object. If no Symbols exist, it returns an
empty array
[].
Code Example: Extracting Hidden Keys
The example below demonstrates the visibility difference between string properties and Symbol properties:
// Create unique Symbols
const id = Symbol('id');
const secretKey = Symbol('secretKey');
// Define an object with both string and Symbol keys
const user = {
name: 'Alex',
role: 'Admin',
[id]: 1042,
[secretKey]: 'sk_live_987654321'
};
// 1. Standard methods ignore Symbols
console.log(Object.keys(user));
// Output: ['name', 'role']
console.log(Object.getOwnPropertyNames(user));
// Output: ['name', 'role']
// 2. Extract only the Symbol keys
const symbolKeys = Object.getOwnPropertySymbols(user);
console.log(symbolKeys);
// Output: [ Symbol(id), Symbol(secretKey) ]
// 3. Access the values using the extracted Symbols
symbolKeys.forEach(sym => {
console.log(`${sym.description}: ${user[sym]}`);
});
// Output:
// id: 1042
// secretKey: sk_live_987654321Retrieving All Keys with Reflect.ownKeys
If you need to extract both standard string keys and hidden Symbol
keys simultaneously in a single operation, use
Reflect.ownKeys(). Under the hood,
Reflect.ownKeys() combines the results of
Object.getOwnPropertyNames() and
Object.getOwnPropertySymbols().
console.log(Reflect.ownKeys(user));
// Output: ['name', 'role', Symbol(id), Symbol(secretKey)]Summary
Symbols in JavaScript provide a layer of obscurity, not true privacy
or security. While general iteration tools overlook Symbol properties,
Object.getOwnPropertySymbols() guarantees that any Symbol
key directly defined on an object can be discovered and accessed.