序列化具有方法的自定义对象。序列化后删除的方法 - 采取什么步骤?

时间:2012-07-16 16:24:50

标签: javascript json serialization

我创建了一个类似于这个简化示例的自定义对象。我的实现为播放列表提供了更复杂的方法:

function Playlist(id) {
    var _songs = [];

    if(!id)
        id = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); });

    var playlist = {
        id: id,
        title: "New Playlist",

        clear: function(){
            _songs = [];
            _save();
        },

        songCount: function () {
            return _songs.length;
        },

        getSongs: function () {
            return _songs;
        }
    }

    return playlist;
}

现在,我有另一个对象,即播放列表,它可以保存播放列表对象:

function playlists(){
    var _playlists = null;
    var _currentPlaylist = null;

    var _save = function () {
        localStorage.setItem('playlists', JSON.stringify(_playlists));
    };

    var _loadPlaylists = function(){
        _playlists = localStorage.getItem('playlists');

        try {
            if (_playlists && _playlists != 'undefined')
                _playlists = JSON.parse(_playlists);
        }
        catch(exception){
            console.error(exception);
        }

        if(!_playlists){
            _playlists = new Array();
            var defaultPlaylist = new Playlist(null, null);

            _playlists.push(defaultPlaylist);
            _save();
        }
    };

    var playlists = {
        count: function(){
            return _playlists.length;
        },

        getPlaylists: function(){
            return _playlists;
        },

        getCurrentPlaylist: function(){
            currentPlaylist = _currentPlaylist;

            if(!currentPlaylist){
                _loadPlaylists();
                currentPlaylist = _playlists[0];
                currentPlaylist.selected = true;
            }

            return currentPlaylist;
        },

        addPlaylist: function(playlistName){
            var playlist = new Playlist(null, playlistName);
            _playlists.push(playlist);
            _save();
        }
    }

    return playlists;
}

当我使用JSON.parse将播放列表对象从JSON转换为对象时,我注意到播放列表对象已被剥离其方法。我相信这是因为JSON.stringify不知道如何(或者它不知道它应该)将对象转换为JSON。

我想知道对此的正确反应是什么?是否可以将方法标记为可序列化?还是需要更多的工作?

2 个答案:

答案 0 :(得分:2)

JSON.stringify()保存数据属性,而不是方法。这就是它的工作原理。

如果您希望它保存您的实际JavaScript代码,那根本就不是它的设计方式。如果需要,可以添加一个数据属性,该属性是对象的自定义类型,当您在对象中回读时,可以使用它来重新附加相应的方法。但是,JSON.stringify()JSON.parse()不会发生这种情况。

如果您事先知道正在阅读的对象类型,则可以创建该类型的对象并将保存的JSON作为初始化程序传递给它。

答案 1 :(得分:1)

如上所述,stringify旨在序列化属性,而不是函数。 我发现this blog post经历了解释原因的过程,最后是如何通过使用__proto__属性来保留对象的函数。看起来现在是唯一的解决方法。