jQuery在初始化过程中会为自己扩展一些基本的静态方法和属性,以下是jQuery 1.11.3版本 239 ~ 564行间所扩展的静态属性和方法

 
 jQuery.extend({

 // 为每个jQuery拷贝建立一个唯一的编号
expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), // 假设jQuery脱离模块支持,已经准备好
isReady: true, // 空转函数
noop: function() {}, /******************* 基本类型判断方法 *****************************/ isFunction: function( obj ) {
return jQuery.type(obj) === "function";
},
isArray: Array.isArray || function( obj ) {
return jQuery.type(obj) === "array";
},
isWindow: function( obj ) { /* jshint eqeqeq: false */
return obj != null && obj == obj.window;
}, isNumeric: function( obj ) {
// 首先抛弃数组, 利用parseFloat返回一个浮点数
// 如果obj是一个合法数字(包括字符串数字),与parseFloat返回值的差是0,因此相减后等0,于是加1
// 如果obj是"0x10",返回值则是0,而obj - 0则会得到16,因此判断"0x10"也是数值
// 如果obj是"abc"等非法数字,会得到NaN - NaN,最终也会得到非数值的判断 return !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0;
},
// 保证obj不包含任何属性
isEmptyObject: function( obj ) {
var name;
for ( name in obj ) { return false;
}
return true;
},
// 最常使用的判断之一,纯对象判断
// 纯对象是有 new 或 {} 创建的对象
// 意味着纯对象不能从其他对象原型中继承而来,只能从Object原型中继承
isPlainObject: function( obj ) {
var key;
// 首先必须是一个object
// 针对IE,需要检查对象的constructor属性
// 把DOM节点和window对象都过滤掉
if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
return false;
}
try {
// Not own constructor property must be Object
if ( obj.constructor && // 不包含构造器
!hasOwn.call(obj, "constructor") &&
!hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
return false;
} } catch ( e ) {
// IE8或9在某些主机上会抛出异常
return false;
}
// 支持: IE<9
// 先处理继承的属性,之后才会处理自身属性
if ( support.ownLast ) {
for ( key in obj ) {
return hasOwn.call( obj, key );
}
}
// 一般浏览器是先遍历自己的属性,因此利用空变量来略过之前的自身属性,直接跳到最后一个属性
// 如果最后一个属性是自身的,那么证明了所有属性都是自身的
for ( key in obj ) {}
return key === undefined || hasOwn.call( obj, key );
}, /********************** 基本工具 **********************/ type: function( obj ) {
if ( obj == null ) {
return obj + ""; // 返回一个字符串 'null'
} // //jQuery初始化过程中会产生一个"class到type"的表
// jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
// class2type[ "[object " + name + "]" ] = name.toLowerCase();
// });
// // 实际上class2type是这样的
// var class2type = {
// "[object Array]": "array",
// "[object Boolean]": "boolean",
// "[object Date]": "date",
// "[object Function]": "function",
// "[object Number]": "number",
// "[object Object]": "object",
// "[object RegExp]": "regexp",
// "[object String]": "string",
// "[object Error]" : "error",
// };
// toString(123) 实际上会返回一个字符串"[object Number]",此时就可以通过class2type表来返回"number"
// type(123) 返回的就是"number"
// 这样做的原因是,对于很多对象,typeof返回的只是object,无法区分具体是什么对象
// 通过object.prototype.toString.call(obj),虽然可以判断出什么对象,但是返回值却不够简练,因此使用了class2type进行映射
return typeof obj === "object" || typeof obj === "function" ?
class2type[ toString.call(obj) ] || "object" : // 通过class2type来返回object类型
typeof obj;
},
// Evaluates a script in a global context
// 在全局上下文上执行一个脚本
globalEval: function( data ) {
if ( data && jQuery.trim( data ) ) {
// IE上使用execScript
// 使用一个匿名函数,从而使上下文在firefox中变成window而非jQuery
( window.execScript || function( data ) {
window[ "eval" ].call( window, data );
} )( data );
}
},
// 转换 dashed to camelCase; CSS和数据模块才使用这个方法
// 首先要去除'-ms-'中的第一个'-'
// 然后删除'-'并将'-'后紧接着的字母转换成大写
// rmsPrefix = /^-ms-/
// rdashAlpha = /-([\da-z])/gi
// fcamelCase = function( all, letter ) {
// return letter.toUpperCase();
// };
camelCase: function( string ) {
return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
},
// 判断elem节点的名字是否为name
// 在后面对节点的操作经常会用到
nodeName: function( elem, name ) {
return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
},
});
总结
  • 基本判断方法里,jQuery.isNumeric的实现过程比较简练,要判断"0x10"这样的十六进制数字,又要判断"1.23"这样的浮点数.该方法里面只使用到了parseFloat,并根据其返回值的特点("字符串前部的合法数字"),只使用一次函数就可判别出数字,实现得非常精明;
  • 纯对象的判断jQuery.isPlainObject也是用得较多的工具,其中针对浏览器的兼容性实现和优化都值得学习;
  • jQuery.type的实现方案更加精彩,因此不同平台上typeof不一定能够准确返回对象的类型,因此需要使用到Object.ptototype.toString方法,然而这个方法会返回不需要的字符,建立一个映射表便可解决这一个问题;

jQuery 源码分析5: jQuery 基本静态方法(一)的更多相关文章

  1. jQuery源码分析之=>jQuery的定义

    最近写前段的代码比较多,jQuery是用的最多的一个对象,但是之前几次看了源码,都没搞清楚jQuery是怎么定义的,今天终于看明白怎么回事了.记录下来,算是一个新的开始吧. (文中源码都是jQuery ...

  2. jQuery 源码分析4: jQuery.extend

    jQuery.extend是jQuery最重要的方法之一,下面看看jQuery是怎样实现扩展操作的 // 如果传入一个对象,这个对象的属性会被添加到jQuery对象中 // 如果传入两个或多个对象,所 ...

  3. jQuery 源码分析3: jQuery.fn/ jQuery.prototype

    // 建立方法实例,提高方法访问的速度(避免在原型链上搜索) var deletedIds = []; var slice = deletedIds.slice; var concat = delet ...

  4. jQuery 源码分析6: jQuery 基本静态方法(二)

    jQuery.extend({ // 遍历obj的所有值 // args 这参数只能内部调用的会用到 // 注意到,如果回调函数调用失败会直接跳出并中止遍历 // 当有args数组时,使用apply调 ...

  5. jQuery 源码分析2: jQuery.fn.init

    //jQuery.fn.intit 中使用到的外部变量: // 判断是否为HTML标签或#id rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w ...

  6. 六.jQuery源码分析之jQuery原型属性和方法

    97 jQuery.fn = jQuery.prototype = { 98 constructor: jQuery, 99 init: function( selector, context, ro ...

  7. jQuery源码分析系列

    声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://git ...

  8. [转] jQuery源码分析-如何做jQuery源码分析

    jQuery源码分析系列(持续更新) jQuery的源码有些晦涩难懂,本文分享一些我看源码的方法,每一个模块我基本按照这样的顺序去学习. 当我读到难度的书或者源码时,会和<如何阅读一本书> ...

  9. jQuery 源码分析 8: 回头看jQuery的构造器(jQuery.fn,jQury.prototype,jQuery.fn.init.prototype的分析)

    在第一篇jQuery源码分析中,简单分析了jQuery对象的构造过程,里面提到了jQuery.fn.jQuery.prototype.jQuery.fn.init.prototype的关系. 从代码中 ...

随机推荐

  1. bzoj3261 可持久化trie

    容易想到题解. 总结一下区间异或和题: 1.转化成trie 2.注意空间稍微开大 3.不要一个数右移31位 4.考虑开头要不要插一个零 5.注意可持久get的时候区间是左开右闭,但这样会变成x-2,x ...

  2. MySQL 索引、视图、DML

    1.索引 索引是存放在模式(schema)中的一个数据库对象,索引的作用就是提高对表的检索查询速度, 索引是通过快速访问的方法来进行快速定位数据,从而减少了对磁盘的读写操作. 索引是数据库的一个对象, ...

  3. MySQL 子查询 EXISTS 和 NOT EXISTS

    MySQL EXISTS 和 NOT EXISTS 子查询 MySQL EXISTS 和 NOT EXISTS 子查询语法如下: SELECT ... FROM table WHERE EXISTS ...

  4. libpq程序例子

    程序: [root@lex tst]# cat testlibpq.c /* * testlibpq.c * Test the C version of LIBPQ, the POSTGRES fro ...

  5. python 闭包(closure)

    闭包的定义: 闭包就是一个函数,这个函数可以记住封闭作用域里的值,而不管封闭作用域是否还在内存中. 来一个例子: def happy_add(a): print 'id(a): %x' % id(a) ...

  6. 理解virtual方法

    1.使用场景 virtual方法的使用场景:父类告诉子类,继承接口,修改实现,从而可以面向接口编程. non-virtual方法的使用场景:父类告诉子类,继承接口和实现,从而可以代码复用. 2.成员方 ...

  7. C#-将控件动态添加到选项卡页tablepage

    tabPage1.Controls.Add(new Button()); 实例: Button cp = new Button(); cp.text="test";cp.Click ...

  8. Centos 7 yum 安装php

    yum install php php-devel 重启apache使php生效 /etc/init.d/httpd restart 此时可以在目录:/var/www/html/下建立一个PHP文件 ...

  9. 深刻理解Python中的元类(metaclass)

    译注:这是一篇在Stack overflow上很热的帖子.提问者自称已经掌握了有关Python OOP编程中的各种概念,但始终觉得元类(metaclass)难以理解.他知道这肯定和自省有关,但仍然觉得 ...

  10. 编写函数,以读模式打开一个文件,将其内容读入到一个string的vector中,将每一行作为一个对立的元素存于vector中

    #include<iostream> #include<string> #include<vector> #include<fstream> using ...