jQuery深入之源码解析(三)——构造jQuery对象

来源:互联网 发布:微信三级分销拼团源码 编辑:程序博客网 时间:2024/05/22 08:03

jQuery构造对象函数有:

  1. jQuery([selector,[context]])
  2. jQuery(element)
  3. jQuery(elementArray)
  4. jQuery(object)
  5. jQuery(jQuery object)
  6. jQuery(html,[ownerDocument])
  7. jQuery(html,[attributes])
  8. jQuery()
  9. jQuery(callback)
function(window,undefined){var jQuery=(function(){    var jQuery = function( selector, context ) {        return new jQuery.fn.init( selector, context );        //这里用new,省去了构造函数jQuery()前面的运算符new,因此我们可以直接写jQuery()    },    //一堆局部变量声明    rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,    rmsPrefix = /^-ms-/,    rdashAlpha = /-([\da-z])/gi,    fcamelCase = function( all, letter ) {        return letter.toUpperCase();    };    //覆盖构造函数jQuery的原型对象    jQuery.fn = jQuery.prototype ={    .....//一堆原型属性和原型方法    };    jQuery.extend = jQuery.fn.extend = function(){    ....//    };    //jQuery.extend()和jQuery.fn.extend(),用于合并两个或多个对象的属性到第一个对象    jQuery.extend({    //一堆静态属性和方法    });    return jQuery;    })();    //其他模块代码    window.jQuery=window.$=jQuery;    })(window);

为什么要覆盖jQuery()的原型对象jQuery.prototype

因为在原型对象jQuery.prototype上定义的属性和方法会被所有jQuery对象继承,可以有效的减少每个jQuery对象所需的内存。

为什么要在构造函数jQuery()内部用运算符new创建并返回另一个构造函数实例

这里写图片描述
用new的原因是因为,我们每次创建一个对象或者实例的时候,都是在运算符后面跟一个new运算符
例如:

var mydate=new Date()

如果构造函数有返回值,运算符new创建的对象会被丢弃,返回值将作为new表达式的值。
jQuery通过在构造函数jQuery()内部用运算符new创建并返回另一个构造函数实例,省去了构造函数jQuery()前面的new,因此我们在创建jQuery对象时可以省略运算符new 直接写jQuery()
后面的

window.jQuery=window.$=jQuery;

也是为了更简写,因此我们在创建jQuery对象时可以写$()=jQuery()=window.jQuery
这里写图片描述
这里写图片描述

jQuery.fn.init()

init = jQuery.fn.init = function( selector, context, root ) {        var match, elem;        //参数selector可以转换为false,如果是"" ,null,undefined,false ,返回this(空的jQuery,length=0if ( !selector ) {            return this;        }        ....        }

一个普通的jQuery对象 $(“body”)
可以看到jQuery.fn.init[1]
length=1
这里写图片描述
一个空的jQuery对象
并且它什么都没有,没有context ,selector,只有原型prototype可以查看原型,它的length=0

这里写图片描述
处理nodeType,文本中有3个p
因此是jQuery.fn.init[3]
这里写图片描述

//如果参数selector是字符串if ( typeof selector === "string" ) {            if ( selector[ 0 ] === "<" &&                selector[ selector.length - 1 ] === ">" &&                selector.length >= 3 ) {                // Assume that strings that start and end with <> are HTML and skip the regex check                match = [ null, selector, null ];            } else {                match = rquickExpr.exec( selector );            }
                   // 处理 $(#id)                    {                    elem = document.getElementById( match[ 2 ] );                    //检查parentNode,因为Blackberry会返回已经不在文档中的Dom节点                    if ( elem && elem.parentNode ) {            //从这里就能看到为id元素构造了length 以及手动设置第一个元素this[0]=elem                        this.length = 1;                        this[ 0 ] = elem;                    }                    //并返回了jQuery对象                    this.context = document;                    this.selector = selector;                    return this;                }
    // Easily-parseable/retrievable ID or TAG or CLASS selectors    //2.2.4版本    // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)    // Strict HTML recognition (#11290: must start with <)    //严格控制了HTML必须以<开头,不识别"ab<div>"    rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/    //1.7.3版本  #是为了防止XSS攻击    quickExpr=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/

说明一下正则表达式
1、2.2.4版本不匹配”ab < d i v >”这样的字符串了,对于“#”也就直接到#id中去识别了,因此省略了 [^#<] (不匹配#和<的字符串,如“abc”)
2、另外说一下(?:pattern),第一次遇到这种表达式(因为平时很少接触正则),这句话的作用是:匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 “或” 字符 (|) 来组合一个模式的各个部分是很有用。例如, ‘industr(?:y|ies) 就是一个比 ‘industry|industries’ 更简略的表达式。
正则语句 rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/的测试:
这里写图片描述
所谓XSS攻击:
只参照《jQuery技术内幕》中的介绍,在应用代码中出现$(location.hash),会根据location.hash的值来执行不同的逻辑。用户可以自行在浏览器地址中修改hash值为”#”,并重新打开这个页面,如果没有#(在jQuery1.6.3之前的版本),”#”会被认为是HTML代码并创建img元素,因为src不存在,oneror事件被触发,从而弹出窗口1。这样攻击者就可以在句柄onerror事件编写恶意代码,例如,读取用户cookie,发起Ajax请求。



本文是在阅读《jQuery技术内幕》后写的,以及慕课网上的jQuery源码解析,也结合了网上的其他对jQuery的分析。
另外我阅读的jQuery源码的version 是 v2.2.4
阅读好的源码有利于对好的代码风格进行学习,由于水平有限,这些都是我的学习心得体会。

0 0
原创粉丝点击