将JSON解析为对象数组

4
我遇到了一个将JSON解析成对象数组的问题。
我有三个JavaScript类:
1. Pet 2. Cat继承Pet 3. Dog继承Pet
我想创建一组Pet对象,然后将其以JSON格式存储在浏览器本地存储中。
问题是:当我检索JSON并将其解析为对象数组时,元素的原型从Cat或Dog更改为Object,所以当我测试时。
pets[0] instanceof Cat // always false
pets[0] instanceof Dog // always false

有没有一种方法可以将元素的原型保留为原始的而不是对象?

这些类:

function Pet(imageUrl, name, soundUrl) {
    this.imageUrl = imageUrl;
    this.name = name;
    this.soundUrl = soundUrl;
    this.talk = function() {
    };
}
function Cat(imageUrl, name, soundUrl, favoriteFood) {
    Pet.apply(this,arguments);
    this.favoriteFood=favoriteFood;
}
Cat.prototype=new Pet();
Cat.prototype.constructor = Cat;
function Dog(imageUrl, name, soundUrl, walkingTime) {
    Pet.apply(this,arguments);
    this.walkingTime=walkingTime;
}
Dog.prototype=new Pet();
Dog.prototype.constructor = Dog;

创建数组后,我需要将其保存在浏览器本地存储中。
var pets=[];
var cat = new Cat('imageUrl','name','soundUrl','favoriteFood');
pets.push(cat);
localStorage.setItem('pets', JSON.stringify(pets));

获取数组:

        if (localStorage.getItem('pets') !== null)
    {
     var pets = JSON.parse(localStorage.getItem('pets'));
    }

无法放置整个代码,因为它太长了。pets被放置在另一个名为HomePage的类中。function HomePage(){ this.pets=[]; } - Mohd Alomar
2个回答

4

是的,JSON中只有普通对象(和数组)。我能想到解决这个问题的唯一方法是添加一个额外的属性来表示类,然后在解析JSON后,您需要将结果对象转换为动物(以某种方式赋予它们生命)。


你有什么建议可以找到属于哪个类的普通对象,以便我可以构造正确的对象吗? - Mohd Alomar
正如我在帖子中所说,我会添加一个属性,比如className,对于猫来说是“Cat”,对于狗来说是“Dog”,以此类推... - Maurice Perry
抱歉我没有看到,我会使用这种方式,它似乎简单而且非常好。 - Mohd Alomar

3
@MauricePerry的答案的一个实现示例:
您想在Pet类中添加一个stringify方法,该方法返回一个纯对象,稍后可以从中实例化动物对象。
示例:
// add stringify function to your Pet class
function Pet(imageUrl, name, soundUrl) {
    ...
    this.stringify = function () {
        var jsonRepresentation = {};
        for (attr in this) {
            if (typeof this[attr] != "function") {
                jsonRepresentation[attr] = this[attr];
            }
        }
        return jsonRepresentation;
    };
};

// add a class property to your various pet subclasses
// e.g. Cat.prototype.class = "cat";

// create an instance of Cat
var cat = new Cat('imageUrl','name','soundUrl','favoriteFood');

// get the info to restore the cat instance later on
var animalInfo = cat.stringify();

/*
cat info would be like:
{
    "class": "cat",
    "imageUrl": "theUrl",
    "name": "theName",
    "soundUrl": "theSoundUrl",
    "favoriteFood": "theFavoriteFood"
}
 */

// then you would store the info to localStorage
...
// later you could retrieve you cat instance like so
var restoredAnimal;
switch(animalInfo.class) {
    case "cat":
        restoredAnimal = new Cat(animalInfo.imageUrl, animalInfo.name, animalInfo.soundUrl, animalInfo.favouriteFood)
        break;
    default:
        console.log('there is no such animal');
}

这个技巧可以很好地配合@MauricePerry的答案。 - Katie Kilian
@erik.eistee 你从哪里得到animalInfo.class的?因为我没有看到叫做class的属性,它是从Object继承来的吗?如果我必须添加它,为什么我不能使用JSON.stringify()? - Mohd Alomar
1
@MohdAlomar 你想要给你的动物子类添加一个类属性,以便稍后区分哪个子类实例化。你可以使用JSON.stringify,但是使用自己的stringify方法,你可以控制你要传递哪些属性(也许有一些私有属性)。 - 321hendrik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接