jQuery的内部全局变量和构造函数

来源:互联网 发布:ios6版本淘宝hd 编辑:程序博客网 时间:2024/06/03 19:26

jQuery外层包装函数

打开任意一个jQuery的源码js文件,都会看到一个匿名自执行函数,如下代码所示。

//()();自执行函数,定义后立马调用(function(window, undefined) {    //... ... })(window);

window是一个全局对象,为什么要把window作为参数传递到框架内部?

  • 调用函数栈时,收索变量顺序是从内到外的方式进行。window作为全局对象而言,肯定是最后才收搜到,那么放到内部可以提高速度;
  • js是具有压缩版本compress,那么在jQuery内部使用window时,压缩后会变成单个字符,如e,那么所有使用window的地方都将访问不都window内的属性,从而造成语法错误,而将window作为参数传递,即使jQuery内window被压缩为字符e,但e任然指向window。

undefined为什么要作为参数?

  • undefined是window下的一个属性,其实在早期的浏览器版本中可以对其进行修改,如IE10以下。 如果外部js环境修改了window.undefined值,那么在函数体内部的undefined判断则不成立。

注释use strict

jQuery为什么注释strict模式? 原因:

  1. strict模式好处
    • 在代码中不能使用一些扩展的保留关键字implements、interface、let、package、private、public、static和yield等;
    • with语句不能使用;
    • 不能申明或重写eval和arguments两个标识符;
    • 不能用delete删除显示申明的标识符、名称或函数;
    • 不能申明8进制;
    • 如果语法检测时发现语法问题,则整个代码块失效,并导致语法异常,如检测对象中的重复键、未申明变量、重复的函数参数;
    • 如果在运行期间出现了违反严格模式的代码,则抛出执行异常。
  2. strict模式限制
    • 必须在全局代码或eval代码或函数申明代码或new Function传入的body开始出引入;
    • 限制8进制在IE10以下不支持和FireFox 18以下不支持。

从strict中可以看到好处就是规范js代码的书写规范和语法检查等功能,那么程序员自身能书写规范化的代码前提下使用strict则显得有些画蛇添足。同时有些浏览器本身也不支持strict模式。

jQuery全局变量

在jQuery源码js中的21~94行是var定义的jQuery内的局部全局变量,这里的局部是指jQuery外层包装函数的变量,而全局是jQuery对象而言。包括如下变量:rootjQuery、readyList、core_strundefined、location、document、docElem、_jQuery、_$、class2type、core_deletedIds、core_version、core_concat、core_push、core_slice、core_indexOf、core_toString、core_hasOwn、core_trim和jQuery、core_pnum、core_rnotwhite、rquickExpr、rsingleTag、rmsPrefix、rdashAlpha、completed等26项。26个变量都起到什么作用是开始阅读源码的起始问题,下面我们根据源码中提供的注释进行翻译。

  • rootjQuery 根节点对象
    “A central reference to the root jQuery(document)”意思是jQuery(document)返回的根节点对象的reference引用,也即在870行有个赋值语句,如下。
// 870All jQuery objects should point back to theserootjQuery = jQuery(document);
  • readyList 用于DOM加载的延迟对象
//826行 readyList = jQuery.Deferred();
  • core_strundefined 表示undefined的字符形式 ——'undefined'
// Support: IE9 表示IE6/7/8都不支持在xml文档节点中通过//xmlNode.method !== undefined方式来检查method是否为undefined// For `typeof xmlNode.method` instead of`xmlNode.method !== undefined`core_strundefined = typeof undefined
  • window参数对应的属性简写
location = window.location, //URL地址对象document = window.document, //文档对象docElem = document.documentElement, //文档HTML元素对象
  • _jQuery、_$保存外部jQuery、$
//356行中的noConflict中,解决外部定义$、jQuery对组件内部的影响。noConflict: function( deep ) {    if ( window.$ === jQuery ) {         window.$ = _$;    }    if ( deep && window.jQuery === jQuery ) {          window.jQuery = _jQuery;    }    return jQuery;},
  • class2type 一个object的对象字面量,用于存储类型简写键值对。
//847行,将常用类型进行组装成toString类型的键值对缓存// Populate the class2type mapjQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {        class2type[ "[object " + name + "]" ] = name.toLowerCase();});
  • jQuery版本和通用方法简写
//缓存被删除的core_deletedIds = [],core_version = "2.0.3", //jQuery版本//通过存储对象方法的引用来提高函数查找速度core_concat = core_deletedIds.concat,core_push = core_deletedIds.push,core_slice = core_deletedIds.slice,core_indexOf = core_deletedIds.indexOf,core_toString = class2type.toString,core_hasOwn = class2type.hasOwnProperty,core_trim = core_version.trim,
  • 正则表达式,用于基本的工具表达式
//用于检测数字表达式,如12,12.9,12e10,12.3e3core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,//用于检测非空白字符,这里\S其实已经一目了然core_rnotwhite = /\S+/g,//一种检测选择器是否HTML字符串的正则表达式,关键在于下面的两句话:Prioritize #id over <tag> to avoid XSS via location.hash (#9521);Strict HTML recognition (#11290: must start with <)//两个子表达式/^(?:\s*(<[\w\W]+>)[^>]*$/和/^#([\w-]*))$/分别是检测HTML字符串、#id选择器rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,//匹配单标签HTML元素,如<input/><div></div>rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,//ms表示micro soft,大家应该明白这是啥意思rmsPrefix = /^-ms-/,//匹配虚线后的单字符,数据0-9和小写字母a-zrdashAlpha = /-([\da-z])/gi,
  • camel字符转换函数fcamelCase
//将虚线转换为camel方式的字符,如"a-d""a-D",而fcamelCase = function( all, letter ) {    return letter.toUpperCase();},//556行,将字符串转换为camel形式的字符串camelCase: function( string ) {    return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );},
  • ready事件处理器complete
completed = function() {     //首次清除load加载事件,然后在手动调用jQuery.ready函数    document.removeEventListener( "DOMContentLoaded", completed, false );    window.removeEventListener( "load", completed, false );    jQuery.ready(); };
  • jQuery对象构造器
    一般封装组件的构造器是是如何做呢?
//定义组件函数function myjQuery () {    this.name = "myjQuery";}//给组件添加功能myjQuery.prototype.init = function() {    //初始化组件}//先创建,在初始化组件var myjQueryObj = new myjQuery();myjQueryObj.init();

在使用jQuery时,jQuery(…)或$(….)获取jQuery对象,那么jQuery对象是如何创建的?下面的代码看出jQuery对象实际是jQuery.fn.init的对象,而jQuery.fn = jQuery.prototype,所以jQuery对象实际是jQuery原型对象函数属性的对象。

jQuery = function( selector, context ) {    // The jQuery object is actually just the init constructor 'enhanced'    return new jQuery.fn.init( selector, context, rootjQuery ); },

总结

jQuery前期定义了许多变量,有函数、正则表达式和常量。这些变量在jQuery框架中发挥了全局作用,在jQuery框架中作为效率、安全和简便的工具。其中jQuery函数是jQuery框架的构造器,从其中看出jQuery在构造对象独特方式所带来编程的体验感好处。

0 0
原创粉丝点击