zoukankan      html  css  js  c++  java
  • jQuery 1.6 源码学习(四)——core.js[4]之链式调用&隐式迭代

    链式调用相对来说简单一点,只需要在每个实例方法的最后返回被操作的对象(一般来说即是this)即可,如下面的remove()方法所示:

    remove: function( selector, keepData ) {
    	for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
    		if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
    			if ( !keepData && elem.nodeType === 1 ) {
    				jQuery.cleanData( elem.getElementsByTagName("*") );
    					jQuery.cleanData( [ elem ] );
    			}
    
    			if ( elem.parentNode ) {
    				elem.parentNode.removeChild( elem );
    			}
    		}
    	}
    	return this;
    },
    

    关于隐式迭代先科普一下,所谓隐式迭代是如下面的代码:

    $("input").val("haha");
    

    这时页面上所有的input的value都会隐式被设置为haha,那么隐式迭代又是如何实现的呢?我们以val为例来看看jQuery的源代码:

    val: function( value ) {
    	var hooks, ret,
    		elem = this[0];
    	//此时将进行取值操作,这里暂不管
    	if ( !arguments.length ) {
    		if ( elem ) {
    			hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
    
    			if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
    				return ret;
    			}
    
    			return (elem.value || "").replace(rreturn, "");
    		}
    
    		return undefined;
    	}
    
    	var isFunction = jQuery.isFunction( value );
    	//设置值的操作,调用了each方法
    	return this.each(function( i ) {
    		var self = jQuery(this), val;
    
    		if ( this.nodeType !== 1 ) {
    			return;
    		}
    
    		if ( isFunction ) {
    			val = value.call( this, i, self.val() );
    		} else {
    			val = value;
    		}
    
    		// Treat null/undefined as ""; convert numbers to string
    		if ( val == null ) {
    			val = "";
    		} else if ( typeof val === "number" ) {
    			val += "";
    		} else if ( jQuery.isArray( val ) ) {
    			val = jQuery.map(val, function ( value ) {
    				return value == null ? "" : value + "";
    			});
    		}
    
    		hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];
    
    		// If set returns undefined, fall back to normal setting
    		if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
    			this.value = val;
    		}
    	});
    

    中间一大段代码不用管,这里我们只需要主要到设置value的代码调用了一个each方法,这个方法便是隐式迭代的核心,简单说来,在每一个需要隐 式迭代的方法中都调用实例each方法,便可以迭代jQuery类数组中的每一个元素。而实例each方法又是通过改变this指向并调用静态each方 法来实现的,如下:

    	each: function( callback, args ) {
    		return jQuery.each( this, callback, args );
    	},
    

    而静态方法的实现分析如下:

    // each 方法只公开了 前两个参数,后一个args只做内部使用
    // args is for internal usage only
    each: function( object, callback, args ) {
    	var name, i = 0,
    		length = object.length,
    		isObj = length === undefined || jQuery.isFunction( object );
    	//内部处理时,将传递相应的args给回调函数
    	if ( args ) {
    		if ( isObj ) {
    			for ( name in object ) {
    				if ( callback.apply( object[ name ], args ) === false ) {
    					break;
    				}
    			}
    		} else {
    			for ( ; i < length; ) {
    				if ( callback.apply( object[ i++ ], args ) === false ) {
    					break;
    				}
    			}
    		}
    	// 在外部使用each函数时,将会迭代object或者array,并且通过检测回调函数的返回值来阻断迭代
    	// A special, fast, case for the most common use of each
    	} else {
    		if ( isObj ) {
    			for ( name in object ) {
    				if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
    					break;
    				}
    			}
    		} else {
    			for ( ; i < length; ) {
    				if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
    					break;
    				}
    			}
    		}
    	}
    
    	return object;
    },
    

    可以看到,each函数相对来说还是比较简单的,更多的细节可以参考jQuery源码分析-each函数,此文作者给出了更加详细的分析说明,当然并非1.6以上版本,不过each函数的差异并不大。

  • 相关阅读:
    vue scrollTop的使用方法
    常见简体繁体转换
    远程桌面发生身份验证错误,要求的函数不受支持
    发布版找不到字体,控制台会报错问题处理
    sql进阶-自增字段的数据修改
    sql序列(6)游标
    sql序列(1)新建文件夹、建库
    sql进阶-触发器的实现
    sql进阶-@@rowcount详解
    单条数据横向滚动
  • 原文地址:https://www.cnblogs.com/firstdream/p/2342685.html
Copyright © 2011-2022 走看看