jquery TypeError: U[a].exec is not a function 是咋个回事


我自行 定义了 js对象原型 Object.prototype.toJSONString = function () { var a = ['{'], // The array holding the text fragments. b, // A boolean indicating that a comma is required. k, ... 展开



这个是jquery构造的问题,jquery官方非常多的提醒过这个,就是不要随便用prototype,会影响到jquery的遍历。

children的实现是一个遍历,你自定义了一个prototype,于是jquery就会遍历到这个,但你这个又是个函数,而不是一个jquery对象

而当你使用("#question_box p") 在jq内部就不是遍历来实现的,而是find


find的实现



find:        function       ( selector ) {      


              


              // 当表达式不包含“,”符号时候      


              


              if        (        this       .length === 1 && !/,/.test(selector) ) {      


              


              var        ret =        this       .pushStack( [],        "find"       , selector );      


              


              ret.length = 0;      


              


              jQuery.find( selector,        this       [0], ret );      


              


              return        ret;      


              


              }       


              


              // 当表达式包含“,”符号时候      


              


              else        {      


              


              var        elems = jQuery.map(       this       ,        function       (elem){      


              


              return        jQuery.find( selector, elem );      


              


              });      


              


              


              


              return        this       .pushStack( /[^+>] [^+>]/.test( selector ) ?      


              


              jQuery.unique( elems ) :      


              


              elems,        "find"       , selector );      


              


              }      


              


       }      


       //其中的jQuery.find是这样一个方法:      


       jQuery.find = Sizzle.find;      


       //而sizzle又是这样一个方法:      


       var        Sizzle =        function       (selector, context, results, seed) {      


              results = results || [];      


              context = context || document;      


              


              if        ( context.nodeType !== 1 && context.nodeType !== 9 )      


              return        [];      


              


              if        ( !selector ||        typeof        selector !==        "string"        ) {      


              return        results;      


              }      


              


              var        parts = [], m, set, checkSet, check, mode, extra, prune =        true       ;      


              


              // Reset the position of the chunker regexp (start from head)      


              chunker.lastIndex = 0;      


              


              while        ( (m = chunker.exec(selector)) !==        null        ) {      


              parts.push( m[1] );      


              


              if        ( m[2] ) {      


              extra = RegExp.rightContext;      


              break       ;      


              }      


              }      


              


              if        ( parts.length > 1 && origPOS.exec( selector ) ) {      


              if        ( parts.length === 2 && Expr.relative[ parts[0] ] ) {      


              set = posProcess( parts[0] + parts[1], context );      


              }        else        {      


              set = Expr.relative[ parts[0] ] ?      


              [ context ] :      


              Sizzle( parts.shift(), context );      


              


              while        ( parts.length ) {      


              selector = parts.shift();      


              


              if        ( Expr.relative[ selector ] )      


              selector += parts.shift();      


              


              set = posProcess( selector, set );      


              }      


              }      


              }        else        {      


              var        ret = seed ?      


              { expr: parts.pop(), set: makeArray(seed) } :      


              Sizzle.find( parts.pop(), parts.length === 1 && context.parentNode ? context.parentNode : context, isXML(context) );      


              set = Sizzle.filter( ret.expr, ret.set );      


              


              if        ( parts.length > 0 ) {      


              checkSet = makeArray(set);      


              }        else        {      


              prune =        false       ;      


              }      


              


              while        ( parts.length ) {      


              var        cur = parts.pop(), pop = cur;      


              


              if        ( !Expr.relative[ cur ] ) {      


              cur =        ""       ;      


              }        else        {      


              pop = parts.pop();      


              }      


              


              if        ( pop ==        null        ) {      


              pop = context;      


              }      


              


              Expr.relative[ cur ]( checkSet, pop, isXML(context) );      


              }      


              }      


              


              if        ( !checkSet ) {      


              checkSet = set;      


              }      


              


              if        ( !checkSet ) {      


              throw        "Syntax error, unrecognized expression: "        + (cur || selector);      


              }      


              


              if        ( toString.call(checkSet) ===        "[object Array]"        ) {      


              if        ( !prune ) {      


              results.push.apply( results, checkSet );      


              }        else        if        ( context.nodeType === 1 ) {      


              for        (        var        i = 0; checkSet[i] !=        null       ; i++ ) {      


              if        ( checkSet[i] && (checkSet[i] ===        true        || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {      


              results.push( set[i] );      


              }      


              }      


              }        else        {      


              for        (        var        i = 0; checkSet[i] !=        null       ; i++ ) {      


              if        ( checkSet[i] && checkSet[i].nodeType === 1 ) {      


              results.push( set[i] );      


              }      


              }      


              }      


              }        else        {      


              makeArray( checkSet, results );      


              }      


              


              if        ( extra ) {      


              Sizzle( extra, context, results, seed );      


              }      


              


              return        results;      


       };

而children的实现方法如下(children就是“>”)

relative: {      


              


              //      


              


              ">"       :        function       (checkSet, part, isXML){      


              


              // 当part为单词字符时,如$("form > input"),part为“form”      


              


              if        (        typeof        part ===        "string"        && !/\W/.test(part) ) {       


              


              part = isXML ? part : part.toUpperCase();       


              


              


              


              for        (        var        i = 0, l = checkSet.length; i < l; i++ ) {      


              


              var        elem = checkSet[i];      


              


              if        ( elem ) {      


              


              // 得到elem的父节点      


              


              var        parent = elem.parentNode;      


              


              // 如果父节点名称为part值时,在checkSet[i]上赋值父节点,否则赋值false      


              


              checkSet[i] = parent.nodeName === part ? parent :        false       ;      


              


              }      


              


              }      


              


              // 当part为非单词字符时,如$(".blue > input"),part为“.blue”      


              


              }        else        {      


              


              for        (        var        i = 0, l = checkSet.length; i < l; i++ ) {      


              


              var        elem = checkSet[i];      


              


              if        ( elem ) {      


              


              checkSet[i] =        typeof        part ===        "string"        ?      


              


              elem.parentNode :      


              


              elem.parentNode === part;      


              


              }      


              


              }       


              


              


              


              if        (        typeof        part ===        "string"        ) {      


              


              Sizzle.filter( part, checkSet,        true        );      


              


              }      


              


              }      


              


              },      


              


       }

看出区别了吗?用的是Sizzle.filter


说道Sizzle,那是相当牛的一个选择器引擎,find和filter是其核心方法之一,他们的区别可以看这个

其中跟你的问题有关的段落摘录如下:

find直接用原生的getElementById(当然也会用byname或者其他)去找

Expr.find  = {       


                ID:         function        ( match, context, isXML ) {       


                if         (         typeof         context.getElementById !==         "undefined"         && !isXML ) {       


                var         m = context.getElementById(match[1]);       


                return         m && m.parentNode ? [m] : [];        


                }       


                },       


                //byclass by name是一样的实现

而children因为只找子一级,不再往下找,所以采取的是两次过滤的方法,即过滤questionbox的下一级元素,然后再看是不是p标签,(在jq的1.2以后的版本里,这个过程是反过来的,似乎,即先找出所有p,然后再看父元素是不是你前一个筛选器,这个机制我记不太清了,懒得去翻源代码看了,你有兴趣可以研究下)

那么,这时候就要用到for in循环,而这时候你又给所有对象定义了新的属性,所以for in的时候必然遍历到你这个新属性,你这个自定义的属性又不是个jq对象,于是自然杯具了。


但奇特的是,我反复测试了你的代码,发现在jq2.0以后的版本上似乎是没问题的。。。难道jq改了选择器的实现?


追问



不太清楚了 我将我页面上的 jquery 改成了2.1.1版本 还是有这个问题 除非去掉那个 原型的定义



追答



嗯 总之最好不要这样用。 也可能是你别的一些方法影响了jq