2014-01-20 2 views
3

В принципе, socket.io использует nativeJSON для кодирования и декодирования пакетов, и моя проблема в том, что я обязан использовать эту версию прототипа, которая изменяет поведение JSON. Когда я должен получить в серверном что-то вроде:PrototypeJS версия 1.6.0.2 Переопределяет JSON.parse и JSON.stringify и разрывает функциональность socket.io

socket.on('event', function (a, b, c), я socket.on('event', function ([a, b, c], undefined, undefined).

Одним из решений является комментировать эти строки на json.js:

/* socket.io-client/lib/json.js 
if (nativeJSON && nativeJSON.parse){ 
    return exports.JSON = { 
     parse: nativeJSON.parse 
    , stringify: nativeJSON.stringify 
    }; 
    } 
*/ 

, но это изменение влияет на производительность серьезно.

Есть ли способ восстановить родные функции JSON? Можно ли создать скрытый iframe для клонирования объекта JSON для восстановления старой функции?

+0

Я не совсем понимаю проблему. Можете ли вы объяснить это немного глубоко? –

ответ

0

Одно решение убить методы расширения прототипа toJSON():

if(window.Prototype) { 
    delete Object.prototype.toJSON; 
    delete Array.prototype.toJSON; 
    delete Hash.prototype.toJSON; 
    delete String.prototype.toJSON; 
} 

Тогда вы должны быть в состоянии использовать собственные JSON.parse/stringify методы в браузере без проблем.

+0

Большое спасибо! – Leo

0

Если вы не хотите, чтобы убить все, и есть код, который будет хорошо на большинстве браузеров, вы могли бы сделать это следующим образом:

(function (undefined) { // This is just to limit _json_stringify to this scope and to redefine undefined in case it was 
    if (true ||typeof (Prototype) !== 'undefined') { 
    // First, ensure we can access the prototype of an object. 
    // See http://stackoverflow.com/questions/7662147/how-to-access-object-prototype-in-javascript 
    if(typeof (Object.getPrototypeOf) === 'undefined') { 
     if(({}).__proto__ === Object.prototype && ([]).__proto__ === Array.prototype) { 
     Object.getPrototypeOf = function getPrototypeOf (object) { 
      return object.__proto__; 
     }; 
     } else { 
     Object.getPrototypeOf = function getPrototypeOf (object) { 
      // May break if the constructor has been changed or removed 
      return object.constructor ? object.constructor.prototype : undefined; 
     } 
     } 
    } 

    var _json_stringify = JSON.stringify; // We save the actual JSON.stringify 
    JSON.stringify = function stringify (obj) { 
     var obj_prototype = Object.getPrototypeOf(obj), 
      old_json = obj_prototype.toJSON, // We save the toJSON of the object 
      res = null; 
     if (old_json) { // If toJSON exists on the object 
     obj_prototype.toJSON = undefined; 
     } 
     res = _json_stringify.apply(this, arguments); 
     if (old_json) 
     obj_prototype.toJSON = old_json; 
     return res; 
    }; 
    } 
}.call(this)); 

Это кажется сложным, но это комплекс только обрабатывать большинство случаев использования. Основная идея - переопределить JSON.stringify, чтобы удалить toJSON из объекта, переданного в качестве аргумента, затем вызвать старый JSON.stringify и, наконец, восстановить его.

Смежные вопросы