douglascrockford / JSON-js

JSON in JavaScript
http://www.JSON.org/
8.69k stars 4.59k forks source link

JSON.decycle() does not preserve functions within objects #139

Closed loglot closed 1 day ago

loglot commented 4 days ago

i'm making objects like this

import { Item } from "item.js"

var list = []
var list[0] = new Item("text info", function func(/* required code */))
var listBak = JSON.stringify(JSON.decycle(list))
list = JSON.retrocycle(JSON.parse(listBak))
console.log(list)

Item being a class that has the variables Text and Func. the log would return [{"Text":"text info"}] when it should return [{"Text":"text info", Func: /* function info */}]

webia1 commented 4 days ago

JSON.stringify won't serialise functions. Since the Func property is a function, it gets lost during serialisation and deserialisation and that's the normal behaviour.

Try this one:

// Custom decycle and retrocycle
function decycleWithFuncs(obj) {
    return JSON.stringify(obj, (key, value) => {
        if (typeof value === 'function') {
            return value.toString();
        }
        return value;
    });
}

function retrocycleWithFuncs(json) {
    return JSON.parse(json, (key, value) => {
        if (typeof value === 'string' && value.startsWith('function')) {
            return eval('(' + value + ')');
        }
        return value;
    });
}

// Assumed your Item class look like:
export class Item {
    constructor(text, func) {
        this.Text = text;
        this.Func = func;
    }
}

var list = [];
list[0] = new Item("text info", function func() {
    /* required code */
});

var listBak = decycleWithFuncs(list);
list = retrocycleWithFuncs(listBak);

console.log(list);

Edit: See online -> TypeScript Playground

loglot commented 3 days ago

Try this one:

when using the TS playground you linked i ran it and got

[LOG]: [{
  "Text": "text info"
}]
douglascrockford commented 1 day ago

JSON does not include functions. Your 'should' statement is incorrect.