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;}