首页 热点资讯 义务教育 高等教育 出国留学 考研考公

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

发布网友

我来回答

2个回答

热心网友

这个是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

热心网友

你这个错误跟你定义的函数没有关系吧。
还有你js的写法,如果有frame的话要确保jQuery属于哪个window,有些浏览器是要有对象后才可以用children的。追问试验过的 我还要将那一段 定义原型的代码注释掉 就不会出错了

追答你的函数可能有问题"堆栈不足",检查是否在无限循环。。。

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com