Maintain the property characteristics (writable, configurable) following the execution of JSON.parse()

Imagine a scenario where an object is created elsewhere and passed to my module. It could have been generated on the server in node.js, or perhaps in a different module where it was then serialized using JSON.stringify() for transmission (especially if it originated from the server). I need to ensure that a specific property of this object remains immutable:

var foo = {};

Object.defineProperty(foo, 'bar', {
    value: 'bar',
    writeable: false,
    enumerable: true
});

console.log(foo.bar); //bar
foo.bar = 'foo';      //fails, throws err in strict
console.log(foo.bar); //still bar

var fii = JSON.parse(JSON.stringify(foo));

console.log(fii.bar); //still bar
fii.bar = 'foo';      //succeeds      
console.log(fii.bar); //now foo

Is there a way to preserve this metadata to ensure the immutability of the bar property without sending it separately?

Answer №1

To serialize the property descriptors, you can convert them to strings like this:

// Define an object for serialization purposes, based on the initial question
var obj = {};
Object.defineProperty(obj, 'prop', {
    value: 'value',
    writable: true,
    enumerable: false
});

// Create an object to store property descriptors
var descriptors = {};
Object.keys(obj).forEach(function(key) {
    descriptors[key] = Object.getOwnPropertyDescriptor(obj, key);
});

var serialized = JSON.stringify(descriptors);
// "{"prop":{"value":"value","writable":true,"enumerable":false,"configurable":false}}"

Now, to deserialize:

descriptors = JSON.parse(serialized);
obj = {};
Object.defineProperties(obj, descriptors);

Keep in mind that this approach may not handle accessor-type descriptors, nested objects, etc.

Using flags within keys

Another technique is to include writability in the key names by applying transformations during serialization and deserialization:

// Indicate non-writable properties by adding ':unwritable' to the key name.
function flagImmutable(object) {
    for (var key in object) {
        if (!Object.getOwnPropertyDescriptor(object, key).writable) {
            object[key + ':unwritable'] = object[key];
            delete object[key];
        }
    }
}
flagImmutable(obj)
> Object {prop:unwritable: "value"}

After stringifying, apply the reverse transformation upon parsing.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issues with Firebase-admin preventing writing to the database are occurring without any error messages being displayed

Issues with Firebase admin writing to the database. The database is instantiated as follows: var db = admin.database(); A reference to the desired table is then set up: var systemsRef = db.ref("systems/"); A function is created to check if a 'sys ...

Finding out which side of a cube has been clicked---Let's identify the side

Currently, I am in the process of developing a navigation menu and I am looking for a way to detect which side the user has clicked. Is it possible to achieve this using raycasting or is there an alternative method that would work better? If you require i ...

Is there a method to track the number of active onSnapshot listeners from Firestore in my application?

In my app, I am implementing a feature that dynamically removes query onSnapshot listeners and replaces them with new ones. To ensure that resources are properly freed up, I need to test the effectiveness of the unsubscribe function. Unfortunately, I do n ...

Having trouble with the "Corrupted @import" error during grunt build?

As I embark on my journey to create my very first Angular application, I have encountered a roadblock. Using Yeoman and angular-generator, everything seemed to be running smoothly with "grunt serve." However, when I attempted to execute "grunt build," the ...

Single input results in array output

I have a pair of items in this array list. $.each(data.recalls,function(i) { var recall = data.recalls[i].nnaId; var description = data.recalls[i].remedyDescription; console.log(recall); console.log(description); $('textarea[name= ...

Create a form action dynamically with JavaScript

html code : <section class="main"> <form class="form-4" name="form4" id="form4" method="POST"> <p class="submit"> <button type="submit" name="submit" onclick="show()"><i class="icon-thumbs-up icon-large"></i> ...

The issue with Jquery Lightbox/Modal doubling upon clicking

Having just started with jQuery, I've encountered an issue with my Gallery Lightbox/Modal. Whenever I click on a thumbnail, the modal reopens itself and I'm unsure where to set a reset. Any help would be greatly appreciated. jQuery(function($) { ...

Is there a way for me to direct to a different HTML page once I click on a certain data point?

At the moment, I have been utilizing this complete set of calendar codes. <!DOCTYPE html> <html> <head> <meta charset='utf-8' /> <link href='fullcalendar.css' rel='stylesheet' /> <link href=&a ...

Exploring the World of Images with Javascript

I'm currently working on creating a slideshow using HTML and JavaScript. My goal is to have the image change each time I press a button that I've established (see code below). After reviewing my code multiple times, I still can't figure out ...

Retrieve the value from a variable located outside an API function call

As I work on developing a chat application project that includes abusive text detection, I have encountered an issue with accessing data from the Perspective API. While I am able to set attributes within the API function, I face challenges accessing them o ...

Swapping out ChildNode data for HTML elements

When attempting to replace a node value with HTML content, I encountered an issue where the HTML tags were being displayed on the HTML page instead of applying the intended style. <style> .YellowSelection { background: yellow; } < ...

Error: The call stack has reached the maximum size limit in nodejs and reactjs

When I attempt to submit the token received from my registration using the code snippet below, I encounter an error stating "maximum call stack exceeded." exports.activationController = (req, res) => { const { token } = req.body; exports.activation ...

Angular facing problems with tracking comment counts in Disqus

After successfully setting up the Disqus comments system on my Angular website following the guide at , everything was working fine. However, when attempting to add the Disqus comment count system to my homepage using the code provided at , I encountered a ...

The display and concealment of a div will shift positions based on the sequence in which its associated buttons are clicked

I am in need of assistance with coding (I am still learning, so please excuse any syntax errors). What I am trying to achieve is having two buttons (button A and button B) that can toggle the visibility of their respective divs (div A and div B), which sh ...

converting specific xml data into a json array in php

The catalog XML file contains information for each book ID, with 5 variables associated with it. <?xml version="1.0"?> <catalog> <book id="bk101"> <author>Gambardella</author> <title>XML Developer</tit ...

Using jQuery to vertically center a div

When a vertical menu on my website is clicked, it pops out from the left side of the screen. The content inside is vertically centered using CSS transformations. While expanding to show sub-items, everything remains centered. However, there's an issue ...

Custom Contract Serialization and Collections in JSON.NET

I am working on creating an IContractResolver to streamline my security management in a WebApi Project. My goal is: To serialize specific objects/properties based on dynamic conditions (such as the Role of the user calling the endpoint). So, I have deve ...

How do I overwrite this calculation using JQuery?

I have a website: link There are two pages on my site that have the same div elements... I want one page to perform a certain calculation on the divs, and another page to perform a different calculation... New JavaScript Code: jQuery(document).ready(fu ...

When the window size is reduced, the navigation vanishes

Whenever I resize the window, the navigation bar disappears. Here is the image of the page before resizing the window https://i.sstatic.net/UiRB9.png Below is the image after resizing the window https://i.sstatic.net/X00d2.png Displayed below is the cod ...

Updating the content of a Telerik RadEditor using Javascript/jQuery

I am currently facing a challenge in manually cleaning the HTML of a Telerik RadEditor using Javascript. Despite my efforts, I am struggling to find the appropriate location to store the value in order for it to be saved during post back. Below is the Jav ...