Сериализация JavaScript и методы - PullRequest
2 голосов
/ 12 марта 2012

Я новичок в "объектно-ориентированном" JavaScript. В настоящее время у меня есть объект, который мне нужно передать по страницам. Мой объект определен следующим образом:

function MyObject() { this.init(); }
MyObject.prototype = {
    property1: "",
    property2: "",

    init: function () {
        this.property1 = "First";
        this.property2 = "Second";
    },

    test: function() {
      alert("Executing test!");
    }
}

На странице 1 моего приложения я создаю экземпляр MyObject. Затем я сериализую объект и храню его в локальном хранилище. Я делаю это, как показано здесь:

var mo = new MyObject();
mo.test();                                    // This works
window.localStorage.setItem("myObject", JSON.stringify(mo));

Теперь на странице 2 мне нужно получить этот объект и поработать с ним. Чтобы получить его, я использую следующее:

var mo = window.localStorage.getItem("myObject");
mo = JSON.parse(mo);
alert(mo.property1);    // This shows "First" as expected.
mo.test();              // This does not work. In fact, I get a "TypeError"  that says "undefined method" in the consol window.

Исходя из результатов, похоже, что когда я сериализовал объект, каким-то образом функции отбрасываются. Я все еще могу видеть свойства. Но я не могу взаимодействовать ни с одной из своих функций. Что я делаю не так?

Ответы [ 5 ]

6 голосов
/ 12 марта 2012

JSON не сериализует функции.

Взгляните на второй абзац здесь .

Если вам нужно сохранить такие значения, вы можетепреобразовывать значения по мере их сериализации или перед десериализацией, чтобы JSON мог представлять дополнительные типы данных.

Другими словами, если вы действительно хотите JSONify функций, вы можете преобразовать их в строки досериализация:

mo.init = ''+mo.init;
mo.test = ''+mo.test;

И после десериализации преобразовать их обратно в функции.

mo.init = eval(mo.init);
mo.test = eval(mo.test);

Однако не должно быть оснований для этого.Вместо этого вы можете сделать так, чтобы ваш MyObject конструктор принял простой объект (как результат анализа строки JSON) и скопировал свойства объекта себе.

3 голосов
/ 12 марта 2012

Функции нельзя сериализовать в объект JSON.

Поэтому я предлагаю вам создать отдельный объект (или свойство внутри объекта) для реальных свойств и просто сериализовать эту часть. После этого вы можете создать экземпляр объекта со всеми его функциями и повторно применить все свойства, чтобы восстановить доступ к вашему рабочему объекту.

Следуя вашему примеру, это может выглядеть так:

function MyObject() { this.init(); }
MyObject.prototype = {
    data: {
      property1: "",
      property2: ""
    },

    init: function () {
        this.property1 = "First";
        this.property2 = "Second";
    },

    test: function() {
      alert("Executing test!");
    },


   save: function( id ) {
     window.localStorage.setItem( id, JSON.stringify(this.data));
   },
   load: function( id ) {
     this.data = JSON.parse( window.getItem( id ) );
   }

}
1 голос
/ 06 декабря 2016

Чтобы избежать изменения структуры, я предпочитаю использовать метод Object.assign при извлечении объекта.Этот метод объединяет второй параметр объекта в первый.Чтобы получить методы объекта, нам просто нужен пустой новый объект, который используется в качестве целевого параметра.

var mo = window.localStorage.getItem("myObject");
// this object has properties only
mo = JSON.parse(mo);
// this object will have properties and functions
var completeObject = Object.assign(new MyObject(), mo);

Обратите внимание, что первый параметр Object.assign изменяется И возвращается функцией.

0 голосов
/ 12 марта 2012

Вы правы, функции сброшены.Эта страница может помочь:

http://www.json.org/js.html

"Значения, которые не имеют представления в JSON (например, функции и неопределенные), исключаются."

0 голосов
/ 12 марта 2012

Это потому, что JSON.stringify() не сериализует функции, я думаю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...