基本上,socket.io使用nativeJSON来包含和解码数据包,我的问题是我不得不使用这个版本的原型来改变JSON行为。当我应该进入服务器时:
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 :(得分:2)
一种解决方案是杀死Prototype的toJSON()扩展方法:
if(window.Prototype) {
delete Object.prototype.toJSON;
delete Array.prototype.toJSON;
delete Hash.prototype.toJSON;
delete String.prototype.toJSON;
}
然后你应该能够毫无问题地使用浏览器的原生JSON.parse / stringify方法。
答案 1 :(得分: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
,最后将其恢复。