jQuery 源码学习之路四(jQuery api 核心==>实用工具系列二)

jQuery.isFunction, jQuery.isNumeric, jQuery.isPlainObject, jQuery.isWindow, jQuery.isXMLDoc, jQuery.merge, jQuery.type, jQuery.makeArray, jQuery.noop, jQuery.now, jQuery.parseJSON, jQuery.trim

来!端起酒杯,拿起碗,磕着花生瓜子咱们就着上篇[! 上篇文章地址链接 ] 接着聊。。。
注意:用法中的测试代码,需要引入jq。

1. 核心==>实用工具 ==>jQuery.isFunction( obj )

$.isFunction(obj)函数用于判断指定参数是否是一个函数。
将要被检查的对象。用于判断该对象是否为函数。
注意:jQuery 1.3之后的版本,例如在 Internet Explorer 中,由浏览器提供的函数alert(),以及 DOM 元素方法(比如 getAttribute())将不被认为是函数。

(1)用法:
1
2
3
4
5
6
function fun(){};
console.log($.isFunction(fun)); //true
var obj = new Object();
console.log($.isFunction(obj)); //false
console.log($.isFunction(null)); //false
console.log($.isFunction("fun")); //false
(2)源码:
1
2
3
isFunction: function( obj ) {
return jQuery.type( obj ) === "function";
}

这个源码就是通过调用jQuery.type方法判断返回值是否为function。

2. 核心==>实用工具==>jQuery.isNumeric( value )

value 用于测试的值。
描述: 确定它的参数是否是一个JavaScript数字。
$.isNumeric()方法检查它的参数是否能代表一个数值。如果是这样,则返回true。否则返回false。该参数可以是任何类型。(jQuery 3.0之前,这个方法会强制转换参数为Number,转换后的值类型如果是如果是Number,也会返回true)
在jQuery 3.0中,$.isNumeric()方法只有接收number类型的参数时候,或者是可以被强制为有限数值的 string类型的参数,才会返回true,在其他情况下,返回false。

(1)用法:
1
2
3
4
console.log($.isNumeric( 0 )); //true
console.log($.isNumeric( "0xFF" )); //true
console.log($.isNumeric( NaN )); //false
console.log($.isNumeric( null )); //false
(2)源码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
isNumeric: function( obj ) {
// As of jQuery 3.0, isNumeric is limited to
// strings and numbers (primitives or objects)
// that can be coerced to finite numbers (gh-2662)
//$.type() 函数用于确定JavaScript内置对象的类型,并返回小写形式的类型名称。
var type = jQuery.type( obj );
//type类型是“number”或“string”,同时运算后不能是NAN,则返回 true
return ( type === "number" || type === "string" ) &&
// parseFloat NaNs numeric-cast false positives ("")
// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
// subtraction forces infinities to NaN
!isNaN( obj - parseFloat( obj ) );
}
//不用原生 typeof 方法的原因:console.log(typeof NaN); //number

3. 核心==>实用工具==>jQuery.isPlainObject( object )

object 用于测试是否为纯粹的对象。
描述: 测试对象是否是纯粹的对象(通过 “{}” 或者 “new Object” 创建的)
注意:检测跨平台时存在很多的不一致,例如在IE8中使用$.isPlainObject()测试document.location

1
2
console.log($.isPlainObject(document.location));
//抛出一个无效的指针异常

(1)用法:
1
2
console.log(jQuery.isPlainObject({})); //true
console.log(jQuery.isPlainObject("test")); //false
(2)源码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
isPlainObject: function( obj ) {
var proto, Ctor;
// Detect obvious negatives
// Use toString instead of jQuery.type to catch host objects
// toString.call( obj ) !== "[object Object]" 判断obj类型不是一个object, apply和call可看我的另一篇文章[!apply]
if ( !obj || toString.call( obj ) !== "[object Object]" ) {
return false;
}
//getProto获取原型链上的对象。var getProto = Object.getPrototypeOf; 用于读取一个对象的 prototype 对象。在源码中一开始的时候就声明了
proto = getProto( obj );
// Objects with no prototype (e.g., `Object.create( null )`) are plain
if ( !proto ) {
return true;
}
// Objects with prototype are plain iff they were constructed by a global Object function
//obj 对象上有 constructor 的属性,hasOwn ==》Object.hasOwnProperty,若obj对象有 constructor 这个属性
//那么 Ctor 的值就是 constructor 这个属性值,即 obj 的构造函数
Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
// 当 Ctor 的类型是 function,且检验 Ctor 最后调用 toString 的方法返回的字符串是否
//是 "function Object() { [native code] }"的字符串,两个条件都满足,则返回 true,表示是纯粹的 object 对象。
return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
}

4. 核心==>实用工具==>jQuery.isWindow( obj )

obj 用于测试是否为一个window对象
描述: 确定参数是否为一个window对象。

(1)用法:
1
2
console.log($.isWindow(window)); //true
console.log($.isWindow(new Object)); //false
(2)源码:
1
2
3
4
isWindow: function( obj ) {
//当前对象不为 null 且 当前对象obj与obj的属性window完全相等,返回 true,否则返回 false
return obj != null && obj === obj.window;
}

5. 核心==>实用工具==>jQuery.isXMLDoc( node )

node 用来检查是否在一个XML文档中的DOM节点。
描述: 检查一个DOM节点是否在XML文档中(或者是一个XML文档)。

(1)用法:
1
2
console.log(jQuery.isXMLDoc(document)) // false
console.log(jQuery.isXMLDoc(document.body)) // false
(2)源码:
1
jQuery.isXMLDoc = Sizzle.isXML; //此处看有关Sizzle的解释,[!Sizzle 文章链接],后补

6. 核心==>实用工具==>jQuery.merge( first, second )

first 第一个用于合并的数组,其中将会包含合并后的第二个数组的内容。
second 第二个用于合并的数组,该数组不会被修改,其中的内容将会被合并到第一个数组中。
描述: 合并两个数组内容到第一个数组。
注意:第一个数组会被修改,所以如需对第一个数组进行其他操作,应先拷贝出来一份数组待用。

(1)用法:
1
2
3
4
5
6
7
8
var first = ['a','b','c'];
var second = ['d','e','f'];
//第一个数组被修改
console.log($.merge(first,second)); // ["a", "b", "c", "d", "e", "f"]
console.log(first); // ["a", "b", "c", "d", "e", "f"]
//不要第一个数组被修改,同时满足两个数组的合并
console.log($.merge( $.merge([],first), second)); //["a", "b", "c", "d", "e", "f"]
console.log(first); //["a", "b", "c"]
(2)源码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
merge: function( first, second ) {
var len = +second.length, // 第二个数组的长度;
j = 0, //初始化 j 的值为 0 ;
i = first.length; // 初始化 i 的值是第一个数组的长度;
//对第二个数组做循环处理,在第一个数组索引值为长度值的位置开始追加第二个数组的值
//说白了,就是在第一个数组后追加第二个数组的值
for ( ; j < len; j++ ) {
first[ i++ ] = second[ j ];
}
//第一个数组的长度就是 first.length + second.length;
first.length = i;
//返回第一个数组
return first;
}

7. 核心==>实用工具==>jQuery.type( obj )

obj 用来获取JavaScript数据类型[[Class]]的对象。
描述: 确定JavaScript 对象的类型[[Class]] 。

(1)用法:
1
2
3
4
console.log(jQuery.type( undefined )); //undefined
console.log(jQuery.type( null )); //null
console.log(jQuery.type( true )); //boolean
console.log(jQuery.type( function(){} )); //function
(2)源码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
type: function( obj ) {
//若 obj 为 null 或 undefined ,则返回字符串 "null""undefined"
if ( obj == null ) {
return obj + "";
}
// Support: Android <=2.3 only (functionish RegExp)
// 如果 obj 是一个 object 或是 function ,那么返回 obj 类型的字符串
return typeof obj === "object" || typeof obj === "function" ?
//class2type[!class2type文章链接]是一个使用tostring()检测对象类返回值的集合,此处若不明白tostring()检测对象类,可看[!apply文章链接]
class2type[ toString.call( obj ) ] || "object" :
//否则返回该 obj 的类型
typeof obj;
}

8. 核心==>实用工具==>jQuery.makeArray( obj )

obj 转换成一个原生数组的任何对象。
描述: 转换一个类似数组的对象成为真正的JavaScript数组。

(1)用法:
1
2
3
4
5
6
7
8
9
10
<div>First</div>
<div>Second</div>
<div>Third</div>
<div>Fourth</div>
<script>
var elems = document.getElementsByTagName("div"); // 返回节点列表
var arr = jQuery.makeArray(elems);
arr.reverse(); // 用数组的方法
$(arr).appendTo(document.body);
</script>
(2)源码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
makeArray: function( arr, results ) {
var ret = results || [];
//判断传入的 arr 是否为 null
if ( arr != null ) {
//判断传入的对象是否是类数组[!isArrayLike文章 ],如果是类数组对象,则调用 jQuery.merge 方法合并数组
if ( isArrayLike( Object( arr ) ) ) {
jQuery.merge( ret,
typeof arr === "string" ? //若是字符串类型,则转换成数组
[ arr ] : arr
);
} else {
//若不是类数组对象,则直接调用Array的push方法,转换成一个原生数组
push.call( ret, arr );
}
}
return ret;
}

makeArray 这个方法从源码可以看出是可以传两个参数的,而且第二个参数应该是数组格式。

9. 核心==>实用工具==>jQuery.noop()

此方法不接受任何参数。
这对一些插件作者很有用,当插件提供了一个可选的回调函数接口,那么如果调用的时候没有传递这个回调函数,就用jQuery.noop来代替执行。

(1)源码:
1
noop: function() {};

10. 核心==>实用工具==>jQuery.now()

此方法不接受任何参数。
$.now()方法是表达式(new Date).getTime()返回数值的一个简写

(1)源码:
1
now: Date.now;

11. 核心==>实用工具==>jQuery.parseJSON( json )

json 要解析的 JSON 字符串。
从jQuery 3.0开始,不推荐使用$.parseJSON。 要解析JSON字符串,请改用原生的 JSON.parse 方法。

(1)源码:
1
jQuery.parseJSON = JSON.parse;

12. 核心==>实用工具==>jQuery.trim( str )

str : The string to trim.
描述: 去掉字符串起始和结尾的空格。

(1)用法:
1
console.log($.trim(" hello, how are you? ")); //hello, how are you? 注意:前后的空格已经去掉了
(2)源码:
1
2
3
4
5
6
7
8
var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
// Support: Android <=4.0 only
trim: function( text ) {
//text 为空,则返回空字符串,否则用正则匹配,去掉前后的空格
return text == null ?
"" :
( text + "" ).replace( rtrim, "" );
}

好了,这篇也先写到这,下一篇接着说。