【jQuery源码】工具函数
//扩展工具函数
jQuery.extend({
// Unique for each copy of jQuery on the page
expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), // Assume jQuery is ready without the ready module
isReady: true, error: function( msg ) {
throw new Error( msg );
}, noop: function() {}, // See test/unit/core.js for details concerning isFunction.
// Since version 1.3, DOM methods and functions like alert
// aren't supported. They return false on IE (#2968).
isFunction: function( obj ) {
return jQuery.type(obj) === "function";
}, //首先判断是否支持ES5中的isArray
isArray: Array.isArray || function( obj ) {
return jQuery.type(obj) === "array";
}, //之前版本是obj && typeof obj === "object" && "setInterval" in obj;
isWindow: function( obj ) {
/* jshint eqeqeq: false */
//window对象是一个包含自己的对象 window.window....window === window;
return obj != null && obj == obj.window;
}, isNumeric: function( obj ) {
// parseFloat NaNs numeric-cast false positives (null|true|false|"")
// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
// subtraction forces infinities to NaN
// adding 1 corrects loss of precision from parseFloat (#15100)
//当不是数字时,(obj - parseFloat( obj ) + 1)为NaN,所以>=0也就为false
return !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0;
}, isEmptyObject: function( obj ) {
var name;
for ( name in obj ) {
return false;
}
return true;
}, // 检查obj是否是一个纯粹的对象(通过"{}" 或 "new Object"创建的对象)
// console.info( $.isPlainObject( {} ) ); // true
// console.info( $.isPlainObject( '' ) ); // false
// console.info( $.isPlainObject( document.location ) ); // true
// console.info( $.isPlainObject( document ) ); // false
// console.info( $.isPlainObject( new Date() ) ); // false
// console.info( $.isPlainObject( ) ); // false
isPlainObject: function( obj ) {
var key; // Must be an Object.
// Because of IE, we also have to check the presence of the constructor property.
// Make sure that DOM nodes and window objects don't pass through, as well
// 必须是一个对象
// 因为在IE8中会抛出非法指针异常,必须检查constructor属性
// DOM节点和window对象,返回false
// obj不存在 或 非object类型 或 DOM节点 或 widnow对象,直接返回false
// 测试以下三中可能的情况:
// jQuery.type(obj) !== "object" 类型不是object,忽略
// obj.nodeType 认为DOM节点不是纯对象
// jQuery.isWindow( obj ) 认为window不是纯对象
if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
return false;
} try {
// Not own constructor property must be Object
// 测试constructor属性
// 具有构造函数constructor,却不是自身的属性(即通过prototype继承的)
if ( obj.constructor &&
!hasOwn.call(obj, "constructor") &&
!hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
return false;
}
} catch ( e ) {
// IE8,9 Will throw exceptions on certain host objects #9897
return false;
} // Support: IE<9
// Handle iteration over inherited properties before own properties.
if ( support.ownLast ) {
for ( key in obj ) {
return hasOwn.call( obj, key );
}
} // Own properties are enumerated firstly, so to speed up,
// if last one is own, then all properties are own.
for ( key in obj ) {} return key === undefined || hasOwn.call( obj, key );
}, type: function( obj ) {
if ( obj == null ) {
return obj + "";//转成字符串的一种方法
}
return typeof obj === "object" || typeof obj === "function" ?
class2type[ toString.call(obj) ] || "object" :
typeof obj;
}, // Evaluates a script in a global context
// Workarounds based on findings by Jim Driscoll
// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
globalEval: function( data ) {
if ( data && jQuery.trim( data ) ) {
// We use execScript on Internet Explorer
// We use an anonymous function so that context is window
// rather than jQuery in Firefox
( window.execScript || function( data ) {
window[ "eval" ].call( window, data );
} )( data );
}
}, // Convert dashed to camelCase; used by the css and data modules
// Microsoft forgot to hump their vendor prefix (#9572)
camelCase: function( string ) {
return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
}, //判断节点名称是否相同
nodeName: function( elem, name ) {
return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
}, // args is for internal usage only
//遍历对象或数组
each: function( obj, callback, args ) {
var value,
i = 0,
length = obj.length,
isArray = isArraylike( obj ); //如果有参数
if ( args ) {
if ( isArray ) {
for ( ; i < length; i++ ) {
value = callback.apply( obj[ i ], args ); if ( value === false ) {
break;
}
}
} else {
for ( i in obj ) {
value = callback.apply( obj[ i ], args ); if ( value === false ) {
break;
}
}
} // A special, fast, case for the most common use of each
//没有参数args则调用,则调用call,上下文设置为当前遍历到的对象,参数设置为key/index和value
} else {
if ( isArray ) {
for ( ; i < length; i++ ) {
value = callback.call( obj[ i ], i, obj[ i ] ); if ( value === false ) {
break;
}
}
} else {
for ( i in obj ) {
value = callback.call( obj[ i ], i, obj[ i ] ); if ( value === false ) {
break;
}
}
}
} return obj;
}, // Support: Android<4.1, IE<9
//利用正则去掉前后空格
trim: function( text ) {
return text == null ?
"" :
( text + "" ).replace( rtrim, "" );
}, // results is for internal usage only
makeArray: function( arr, results ) {
var ret = results || []; if ( arr != null ) {
if ( isArraylike( Object(arr) ) ) {//伪数组
jQuery.merge( ret,
typeof arr === "string" ?
[ arr ] : arr
);
} else {//不是数组也不是伪数组
push.call( ret, arr );
}
} return ret;
}, //在数组中搜索指定的值,并返回其索引值,i为查找的起始位置
inArray: function( elem, arr, i ) {
var len; if ( arr ) {
if ( indexOf ) {// 是否有本地化的Array.prototype.indexOf
return indexOf.call( arr, elem, i );
} len = arr.length;
i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; for ( ; i < len; i++ ) {
// Skip accessing in sparse arrays
//i in arr表示arr[i]存在
if ( i in arr && arr[ i ] === elem ) {
return i;
}
}
} return -1;
}, //将数组second合并到数组first中
merge: function( first, second ) {
var len = +second.length,
j = 0,
i = first.length; while ( j < len ) {
first[ i++ ] = second[ j++ ];
} // Support: IE<9
// Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)
//在IE9以前,类数组对象的length为NaN
if ( len !== len ) {
while ( second[j] !== undefined ) {
first[ i++ ] = second[ j++ ];
}
} first.length = i; return first;
}, // 过滤数组,返回新数组;callback返回true时保留;如果inv为true,callback返回false才会保留
grep: function( elems, callback, invert ) {
var callbackInverse,
matches = [],
i = 0,
length = elems.length,
callbackExpect = !invert; // Go through the array, only saving the items
// that pass the validator function
//遍历数组,将回调函数返回值push到结果数组
for ( ; i < length; i++ ) {
callbackInverse = !callback( elems[ i ], i );
if ( callbackInverse !== callbackExpect ) {
matches.push( elems[ i ] );
}
} return matches;
}, // arg is for internal usage only
//将数组或对象elems的元素/属性,转化成新的数组
map: function( elems, callback, arg ) {
var value,
i = 0,
length = elems.length,
isArray = isArraylike( elems ),
ret = []; // Go through the array, translating each of the items to their new values
if ( isArray ) {//类数组或数组
for ( ; i < length; i++ ) {
value = callback( elems[ i ], i, arg ); if ( value != null ) {
ret.push( value );
}
} // Go through every key on the object,
} else {//对象
for ( i in elems ) {
value = callback( elems[ i ], i, arg ); if ( value != null ) {
ret.push( value );
}
}
} // Flatten any nested arrays
// 使嵌套数组变平
// concat:
// 如果某一项为数组,那么添加其内容到末尾。
// 如果该项目不是数组,就将其作为单个的数组元素添加到数组的末尾。
return concat.apply( [], ret );
}, // A global GUID counter for objects
guid: 1, // Bind a function to a context, optionally partially applying any
// arguments.
// 代理方法:为fn指定上下文(即this)
proxy: function( fn, context ) {
var args, proxy, tmp; //如果context是字符串格式,fn为fn[context]
//上下文环境设为fn
if ( typeof context === "string" ) {
tmp = fn[ context ];
context = fn;
fn = tmp;
} // Quick check to determine if target is callable, in the spec
// this throws a TypeError, but we will just return undefined.
// 快速测试fn是否是可调用的(即函数)
// 但是这里仅返回undefined
if ( !jQuery.isFunction( fn ) ) {
return undefined;
} // Simulated bind
args = slice.call( arguments, 2 );//从列表中去除前两个参数,即fn,context
proxy = function() {
return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
}; // Set the guid of unique handler to the same of original handler, so it can be removed
proxy.guid = fn.guid = fn.guid || jQuery.guid++; return proxy;
}, now: function() {
return +( new Date() );
}, // jQuery.support is not used in Core but other projects attach their
// properties to it so it needs to exist.
support: support
});
【jQuery源码】工具函数的更多相关文章
- 我被冻在了 vue2 源码工具函数第一行Object.freeze()(一)
前言 最近参加若川的源码共度活动,第 24 期 vue2 源码工具函数,最开始: var emptyObject = Object.freeze({}); 之前知道 Object.freeze() 是 ...
- jquery 源码学习(四)构造jQuery对象-工具函数
jQuery源码分析-03构造jQuery对象-工具函数,需要的朋友可以参考下. 作者:nuysoft/高云 QQ:47214707 EMail:nuysoft@gmail.com 声明:本文为原 ...
- jQuery源码逐行分析学习02(第一部分:jQuery的一些变量和函数)
第一次尝试使用Office Word,方便程度大大超过网页在线编辑,不过初次使用,一些内容不甚熟悉,望各位大神见谅~ 在上次的文章中,把整个jQuery的结构进行了梳理,得到了整个jQuery的简化结 ...
- 原生JS研究:学习jquery源码,收集整理常用JS函数
原生JS研究:学习jquery源码,收集整理常用JS函数: 1. JS获取原生class(getElementsByClass) 转自:http://blog.csdn.net/kongjiea/ar ...
- jQuery源码分析-each函数
本文部分截取自且行且思 jQuery.each方法用于遍历一个数组或对象,并对当前遍历的元素进行处理,在jQuery使用的频率非常大,下面就这个函数做了详细讲解: 复制代码代码 /*! * jQuer ...
- Jquery源码学习(第一天)
jQuery是面向对象的设计通过window.$ = window.jQuery = $; 向外提供接口,将$挂在window下,外部就可以使用$和jQuery $("#div1" ...
- jQuery源码:从原理到实战
jQuery源码:从原理到实战 jQuery选择器对象 $(".my-class"); document.querySelectorAll*".my-class" ...
- 读jQuery源码 - Callbacks
代码的本质突出顺序.有序这一概念,尤其在javascript——毕竟javascript是单线程引擎. javascript拥有函数式编程的特性,而又因为javascript单线程引擎,我们的函数总是 ...
- jQuery源码笔记(一):jQuery的整体结构
jQuery 是一个非常优秀的 JS 库,与 Prototype,YUI,Mootools 等众多的 Js 类库相比,它剑走偏锋,从 web 开发的实用角度出发,抛除了其它 Lib 中一些中看但不实用 ...
- jQuery源码分析-01总体架构
1. 总体架构 1.1自调用匿名函数 self-invoking anonymous function 打开jQuery源码,首先你会看到这样的代码结构: (function( window, und ...
随机推荐
- VIM 正则表达式详解及与 perl 正则的区别
转载自:http://www.xuebuyuan.com/806332.html:个人进行了一些修正和添加. 下面我们对 VIM 正则表达式进行介绍并会显示指出其与 Perl 正则的不同之处. 字符集 ...
- (KMP)Oulipo -- poj --3461
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=92486#problem/B http://poj.org/problem?id=3461 ...
- (最短路 Floyd)Cow Contest --POJ--3660
链接: http://poj.org/problem?id=3660 思路: 1. 1->2->3==1->3 2. 记录每次的比赛人员 3. 每个人只能跟他序号不同的人比赛, ...
- (最小生成树) Jungle Roads -- POJ -- 1251
链接: http://poj.org/problem?id=1251 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 2177 ...
- Hbase和Hive的异同
共同点:1.hbase与hive都是架构在hadoop之上的.都是用hadoop作为底层存储 区别:2.Hive是建立在Hadoop之上为了减少MapReduce jobs编写工作的批处理系统,HBa ...
- hibernate 延迟加载深入分析(persistentSet的延迟加载)
Hibernae 的延迟加载是一个非常常用的技术,实体的集合属性默认会被延迟加载,实体所关联的实体默认也会被延迟加载.Hibernate 通过这种延迟加载来降低系统的内存开销,从而保证 Hiberna ...
- Android Studio生成get,set,tostring,构造方法
如何在AndroidStudio开发Android应用程序的时候,在对象模型中生成快捷方式生成get,set,tostring,构造方法等: 有两种方式: 第一种方式:Code –> Gener ...
- sqlServer数据库纵横表相互转化
sqlServer 数据库纵横表相互转化 一.纵表转横表: 1.纵表: 2.横表: 3. 代码: select Name as '姓名', end) as '语文', end) as '数学', e ...
- 网易云首席安全架构师谈安全新形势:DDOS两三天,游戏玩家数从几万降到几百
本文由 网易云发布. 安全是一个永恒的话题,在业务不断云化.攻击越来越复杂的当下,互联网安全呈现了出什么样的严峻形势?对这些形势,网易云又是如何应对的? 网易云首席安全架构师沈明星 4月13日,网易 ...
- Kafka迁移与扩容工具用法
1.迁移topic到新增的node上 假如现在一个kafka集群运行三个broker,broker.id依次为101,102,103,后来由于业务数据突然暴增,需要新增三个broker,broker. ...