【问题标题】:Serializing a JavaScript Object to JSON returns "{}", but why?将 JavaScript 对象序列化为 JSON 会返回“{}”,但为什么呢?
【发布时间】:2014-07-30 12:06:37
【问题描述】:

你好 StackOverflowers,

我正在为我的 Web 应用程序实现一个 LocalStorage 系统。

但我很遗憾的是,Model抽象层中的所有对象都必须序列化。

我知道当对象转换为 JSON 时,函数不会被序列化。

我正要使用Option 1 described here。 (也就是说,创建一个“静态”方法,该方法返回一个包含函数的全新对象)。

但是,问题是即使对象的非函数成员也没有被转换。

例如在 divvie.textContent = JSON.stringify(coffee); 处,divvie.textContent 变为“{}”。

为什么?这是怎么回事?

示例代码,不是我的真实应用程序,但情况大致相同: 检查咖啡

                var coffee = new Coffee( "0001", "DE Red Coarse",
                    "Douwe Egberts, red & coarse grounded." );
                coffee.addSugarCube( "0x0F_BROWN", "15" );
                coffee.addSugarCube( "0x0C_WHITE", "12" );

                var divvie = document.getElementById( "run" );
                divvie.textContent = JSON.stringify( coffee );
        </script>
    </body>
</html>

/**
 * @class This class represents a coffee.
 *
 * @param {String} id
 * @param {String} name
 * @param {String} description
 * @returns {Coffee}
 */
function Coffee( id, name, description )
{
    var sugarCubes = new Array();

    var maxAmountOfSweetness = 0;

    /**
     * @returns {String}
     */
    this.getId = function()
    {
        return id;
    };

    /**
     * @returns {String}
     */
    this.getName = function()
    {
        return name;
    };

    /**
     * @returns {String}
     */
    this.getDescription = function()
    {
        return description;
    };

    /**
     * @param {String} sugarCubeId
     * @param {Number} amountOfSweetness
     */
    this.addSugarCube = function( sugarCubeId, amountOfSweetness )
    {
        /// First check if this sugarCube is already in our coffee.
        var sugarCubeFound = false;

        for( var i = 0; i < sugarCubes.length; i++ )
        {
            if( sugarCubes[ i ].getId() === sugarCubeId )
            {
                sugarCubeFound = true;

                i = sugarCubes.length;
            }
        }

        if( !sugarCubeFound )
        {
            /// Oh Sweet! A new sugar cube to add in our coffee!
            sugarCubes.push( new SugarCube( sugarCubeId, amountOfSweetness ) );
            maxAmountOfSweetness = Math.max( maxAmountOfSweetness, amountOfSweetness );
        }
    };

    /**
     * @param {String} sugarCubeId
     * @returns {SugarCube}
     */
    this.getSugarCube = function( sugarCubeId )
    {
        for( var i = 0; i < sugarCubes.length; i++ )
        {
            if( sugarCubes[ i ].getId() === sugarCubeId )
            {
                return sugarCubes[ i ];
            }
        }
    };

    /**
     * @returns {Boolean} True when the amount of sugar cubes in this coffee is 1 or more,
     * false when not.
     */
    this.isSweet = function()
    {
        if( 0 < sugarCubes.length )
        {
            return true;
        }
        return false;
    };
}

/**
 * @class This class represents a sugar cube
 *
 * @param {String} id
 * @param {Number} amountOfSweetness
 * @returns {SugarCube}
 */
function SugarCube( id, amountOfSweetness )
{
    /**
     * @returns {String}
     */
    this.getId = function()
    {
        return id;
    };

    /**
     * @returns {Number}
     */
    this.getAmountOfSweetness = function()
    {
        return amountOfSweetness;
    };
}

【问题讨论】:

    标签: javascript json serialization stringify


    【解决方案1】:

    Coffee 构造函数创建的实例的唯一属性似乎是方法,它们没有 JSON 表示(因为它们是 函数)。您的 data 全部保存为 variables 或创建的闭包中的参数。这些不是 属性,因此也不是 JSON 的设计目的。

    要使其按预期工作,您需要编写自己的 toJSON 方法,或者将数据从 vars 移动到属性

    例如,使用属性

    function Coffee(id, name, description) {
        this.id = id;
        this.name = name;
        this.description = description;
        this.sugarCubes = [];
        this.maxAmountOfSweetness = 0;
    }
    // and now you could even move the methods into the prototype
    Coffee.prototype = {
        getId: function () {return this.id;}
        // etc
    
    };
    // new Coffee() is now JSON-able
    

    您可能使用var 来“隐藏”数据,因此它仅通过您的方法公开,因此另一种方法是添加一个将其转换为 JSON 的新方法,例如 p>

    // in Coffee
    this.toJSON = function (a, b) {
        var o = {
            id: id,
            name: name
            // etc
        };
        return JSON.stringify(o, a, b);
    };
    

    【讨论】:

    • this.toJSON() 的参数“a”和“b”是 JSON.stringify() 中的“replacer”和“space”,对吗?

      PS:关于我在这里使用 var 和 this 的说法是正确的。我是用 Java 和 C++ 长大的,所以我使用“var”作为“私有”访问修饰符,使用“this”作为“公共”访问修饰符。
    • @RoestVrijStaal 确实,你没有支持他们,但我想为什么不
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-25
    • 1970-01-01
    • 2011-09-23
    相关资源
    最近更新 更多