json.js与jquery冲突too much recursion/Stack Overflow

  json.js文件和jquery序列化JSON对象为键值对的方法param产生冲突,导致json.js文件中的toJSONString方法重复调用自身从而堆栈溢出出现too much recursion【firefox】/Stack Overflow【IE浏览器】错误。

  产生too much recursion/Stack Overflow这个问题主要是jquery调用ajax方法时,如果参数为json对象,jquery会调用param方法序列化json对象为键值对,param方法中使用了for语句遍历json对象,而json.js对object对象扩展了toJSONString方法,导致jquery遍历到参数的toJSONString方法时,分离了对象toJSONString方法来执行,导致toJSONString方法执行时的上下文被改为window,而json.js有个bug就是当window.toJSONString()时会发生递归调用toJSONString(),从而循环调用而导致堆栈溢出现too much recursion【firefox】/Stack Overflow【IE浏览器】错误。
 

  下面为jquery方法param和json.js的大概结构代码,为了示例方便,简写如下

//====================jquery param大概代码模拟 =============================
var s = [];
        var o = { }
        //alert($.param(o))//
        for (var attr in o) add(attr, o[attr]);
        function add(key, value) {
            // If value is a function, invoke it and return its value
            value = typeof (value) == 'function' ? value()/*这里分离toJSONString后执行会改变json.js中toJSONString方法中的this==window对象*/ 
                    : value;
            s[s.length] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
        }

//=====================json.js中toJSONString方法中的主要实现代码================
        for (k in this) {
            if (typeof k === 'string'&&Object.prototype.hasOwnProperty.apply(this, [k])) {
                v = this[k];//this为window时此时v为toJSONString方法
                switch (typeof v) {
                    case 'object':
                        //if (v == this) continue;////
                        // Serialize a JavaScript object value. Ignore objects that lack the
                        // toJSONString method. Due to a specification error in ECMAScript,
                        // typeof null is 'object', so watch out for that case.

                        if (v) {
                            if (typeof v.toJSONString === 'function') {
                                a.push(k.toJSONString() + ':' + v.toJSONString());//这里执行v.toJSONString实际执行的是window.toJSONString方法,导致循环自身调用了
                            }
                        } else {
                            a.push(k.toJSONString() + ':null');
                        }
                        break;

                    case 'string':
                    case 'number':
                    case 'boolean':
                        a.push(k.toJSONString() + ':' + v.toJSONString());
                        // Values without a JSON representation are ignored.
                }
            }
        }


  解决方法:修改json.js文件,找到switch (typeof v) { case 'object': 差不多的语句,如果是从本站下载的json.js文件,大概在150~152行之间,增加一个是否自身调用的判断即可解决循环调用堆栈溢出too much recursion【firefox】/Stack Overflow【IE浏览器】错误。

switch (typeof v) {
                case 'object':
                    if (v == this) continue;//增加是否自身调用,为自身调用会导致堆栈溢出。所以需要pass掉。
                    // Serialize a JavaScript object value. Ignore objects that lack the
                    // toJSONString method. Due to a specification error in ECMAScript,
                    // typeof null is 'object', so watch out for that case.

                    if (v) {
                        if (typeof v.toJSONString === 'function') {
                            a.push(k.toJSONString() + ':' + v.toJSONString());
                        }
                    } else {
                        a.push(k.toJSONString() + ':null');
                    }
                    break;

                case 'string':
                case 'number':
                case 'boolean':
                    a.push(k.toJSONString() + ':' + v.toJSONString());

                    // Values without a JSON representation are ignored.

            }


或者重新下载json.js文件,就可以解决json.js与jquery冲突问题。

加支付宝好友偷能量挖...


原创文章,转载请注明出处:json.js与jquery冲突too much recursion/Stack Overflow

评论(0)Web开发网
阅读(1273)喜欢(0)JavaScript/Ajax开发技巧