【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 ...
随机推荐
- cmake-file
file: File manipulation command. file(WRITE filename "message to write"... ) file(APPEND f ...
- Oracle之SQL语句性能优化(34条优化方法)
(1)选择最有效率的表名顺序(只在基于规则的优化器中有效): ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driving table)将被最先处 ...
- 好用的SHELL小编程
1>判断输入为数字,字符或其他 脚本代码: 检测结果: 2>求平均数: 测试效果: 3>自减输出: 脚本代码: 测试效果: 4>在文件 ...
- Android-fragment的替换-V4支持包
昨天写的这几篇博客,Android-fragment简介-fragment的简单使用,Activity-fragment-ListView展示,Android-fragment生命周期,Android ...
- Quartz.net 起步
安装 Quartz 程序包 使用 nuget 命令行安装 Quartz: Install-Package Quartz 如果使用 JSON 序列化,使用 nuget 安装 Quartz.Seriali ...
- AndroidPn源码分析(二)
接上篇: (一)客户端与服务器建立连接 上一篇写到ClientSession createClientSession这里,创建一个客户端的session.在SessionManager类中创建了ses ...
- linux系统编程之进程(一):进程与程序
本节目标: 什么是程序 什么是进程 进程数据结构 进程与程序区别与联系 一,什么是程序? 程序是完成特定任务的一系列指令集合 二,什么是进程? 从用户的角度来看进程是程序的一次动态执行过程 从操作系统 ...
- With语句上下文管理
在平时工作中总会有这样的任务,它们需要开始前做准备,然后做任务,然后收尾清理....比如读取文件,需要先打开,读取,关闭 这个时候就可以使用with简化代码,很方便 1.没有用with语句 1 2 3 ...
- kolla-ansible 源码下载
下载地址: https://pypi.org/project/kolla-ansible/ ansible下载: https://releases.ansible.com/ansible/rpm/re ...
- python学习笔记6-集合
# 集合是无序且不可重复的元素的集合 a = set([1,3,1,3,3,2,2,5]) a # {1, 2, 3, 5} b = set(range(2,5)) b # {2, 3, 4} # 1 ...