Skip to content
Advertisement

Reflect API and Serialization via JSON.stringify

The following JavaScript code does something I didn’t expect.

let foo = {};
Reflect.defineProperty(foo,'bar',{value:1});
console.log(foo); // { bar: 1 }
console.log(JSON.stringify(foo)); // { }

Why is the serialized output from JSON.stringify missing the new bar property?

Advertisement

Answer

because this property is not enumerable.

By default, properties added using Object.defineProperty() are not writable, not enumerable, and not configurable.

see documentation : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty#description

let foo = {};
Reflect.defineProperty(foo,'bar',{value:1});

console.log( JSON.stringify(foo));             // {}
console.log( foo.hasOwnProperty('bar'))        // true
console.log( foo.propertyIsEnumerable('bar') ) // false

so you must do:

let foo = {};
Reflect.defineProperty(foo,'bar',{enumerable: true, value:1});

console.log( JSON.stringify(foo));             // {"bar":1}

This is similar for the length property upon arrays:

let arr = ['a','b','c']

console.log( arr.length )                         // 3
console.log( Object.getOwnPropertyNames(arr)  );  // [ "0", "1", "2", "length" ]
console.log( arr.hasOwnProperty('length'))        // true 
console.log( arr.propertyIsEnumerable('0') )      // true
console.log( arr.propertyIsEnumerable('length') ) // false
.as-console-wrapper {max-height: 100% !important;top: 0;}
.as-console-row::after {display: none !important;}
User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement