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

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, ... 展开
laodai11 | 浏览 9680 次
发布于2014-09-19 02:56 最佳答案

这个是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是其核心方法之一,他们的区别可以看这个:

http://www.cnblogs.com/xesam/archive/2012/02/15/2352574.html

http://www.cnblogs.com/xesam/archive/2012/02/18/2356617.html

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

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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值