Аргумент данных historyjs/HTML5 pushState не сохраняет свойства объекта, которые являются функциями

Я пытаюсь использовать pushState в своем веб-приложении следующим образом:

//default settings
    var ds = {
        path: window.module.Globals.prototype.base_url, //location misc variable for my app
        type: 'POST',
        dataType: 'html',
        data: {},
        target: 'main_swap_area',
        pre_ajax_callback: function(scope){ console.log('pac'); },
        post_success_callback: function(data, textStatus, jqXHR, scope){ console.log('psc'); },
        scope: this
    };

    History.pushState(ds, 'Title 1', ds.path);

И у меня есть функция обратного вызова, прослушивающая событие «statechange»

jQuery(window).bind('statechange',function(){


        var
            State = History.getState(),
            url = State.url;

        console.log(State); // State.data is object with all original properties EXCEPT properties that contained functions as values


    }); // end onStateChange

Вывод моей консоли - это объект со всеми моими исходными свойствами/значениями, кроме всех свойств, которые имели функции для значений. Почему их сбрасывают/не возвращают?


person Casey Flynn    schedule 25.06.2012    source источник


Ответы (2)


В какой-то момент многие реализации pushState использовали JSON для сериализации и десериализации объектов. В новых версиях браузеров используется так называемый алгоритм структурированного клонирования.

В обоих случаях объекты Error и Function не поддерживаются, поэтому их нельзя использовать как часть состояния pushState. Попытка сделать это обычно приводит к исключению DATA_CLONE_ERR, но, возможно, событие ошибки не всплывает.

Если вы действительно хотите сохранить функцию, я вижу, что алгоритм структурированного клонирования поддерживает клонирование Blob, поэтому вы можете загрузить свою функцию как узел <script> с возможным сохранением этого текстового блоба как Blob в локальном хранилище. Вам придется eval использовать его (что может быть опасно при неправильном использовании), но я видел, как что-то подобное работает, хотя и не совсем элегантно.

person buley    schedule 26.06.2012

Просто мысль: почему бы не передать имя функции через json, если оно существует в данных, создайте новую функцию, а затем выполните ее

temp = new Function(State.data.pre_ajax_callback);
temp();
person Shawn C    schedule 09.10.2012