?理解jQuery

Posted yangfengyi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了?理解jQuery相关的知识,希望对你有一定的参考价值。

jQuery

  jQuery原理: 

  jQuery通过立即执行函数封闭作用域,将全局作用域window和所有的方法通过参数的方式传入到这个模块当中,形式大致是这样的:    

1 (function(global, factory){
2     factory(global);
3 })(window, function(window){
4     // 所有的功能代码都放在这里面
5 })

  这种倒置代码运行顺序的方式是立即执行函数(IIFE)的一种变化的用途,将需要运行的函数放在第二位,在立即执行函数执行之后当作参数传递进去,这种模式也被称为UMD(Universal Module Definition)。

  init函数:

  在jQuery当中init函数的作用是将传入各种形式的参数构造成jQuery对象,例如我们使用$(‘#demo‘)来获取DOM元素的时候,就是将id为demo的dom元素转变成jQuery对象,下面是init 函数的实现转变过程的实现:

 1   // 这只是一个简单的模拟实现而已
 2 (function(global, factory){
 3     factory(global);
 4 })(window, function(){
 5   // 将jQuery和$暴露到全局作用域下
 6   window.jQuery = window.$ = jQuery;
 7   // 为了实现无new操作,jQuery就借用了一下init函数的劳动成果
 8   function jQuery(str){
 9       return new jQuery.prototype.init(str);
10   }
11     // 实际上的功能函数,实现创建jQuery对象。
12   jQuery.prototype.init = function(str){
13       this[0] = document.getElementById(str);
14       this.length = 1;
15    }
16 })
17 console.log(jQuery(‘demo‘));//div#demo被选出    

  可以看出当我们使用$( )来选择dom的元素的时候,其实并不是jQuery这个函数在工作,而是他背后的init的功劳, 并且还将这个init函数收入麾下,放在了自己的prototype上面,但是问题出来了,虽然抢占了init构造函数的功劳,但是我们知道当我们使用jQuery对象的时候,要使用的是对象上面的方法啊,但是这里的init.prototype是执行Object的,上面并没有自定义的方法。所以jQuery做出了更加无耻的事情,就是强行让init构造函数的prototype指向自己prototype。

jQuery.prototype.init.prototype = jQuery.prototype

  终于jQuery达到了自己的目的,为了实现不new构造出对象,借用了一个init函数,为了构造出来的对象能使用自己原型上面的方法,将init构造函数的prototype指向自己的prototype上面。

  init函数的选择原理:

  在jQuery当中,可以像css选择器一般的选择dom元素,使用方法很灵活,是jQuery内部对传入的参数做了很大的文章

  init方法有三个参数: $( ‘ ‘, ‘ ‘, ‘ ‘);

    selector : $() 当中的第一个参数

    context : $() 当中的第二个参数

    root : $() 当中的第三个参数(默认的是$(document))

  实现机理:

1. 如果 $( ) 中第一个参数传递的是 空 ,直接返回本身 ---> $( ) / $(null) / $(undefined) / $(false)
2. 如果 $( ) 中第一个参数传递的是字符串
  (1) 如果字符串是一个标签且长度大于或等于三 ---> $(‘<div></div>‘) 创建标签的模式
       传递到一个长度为三match数组的第二位 ---> match[‘‘,‘<div></div>‘,‘‘] 
  (2) 否则进入一个正则匹配 *如果字符串中含有合法的标签 --->$(‘<div/>123‘)根据正则表达式提取出合法的标签, 传入到match数组的第二位,match[‘‘, ‘<div/>‘, ‘‘] *如果字符串是以‘#‘开头,证明是一个id,且后面跟着一个合法的字符串 --->$(‘#id‘) 根据正则表达式提取这个合法的字符串,传递到match数组的第三位 ---> match[‘‘,‘‘,‘id‘] (3) 如果match数组不为空 *若match数组第二位有值,生成dom,如果$()有第二个参数,且第二个参数是一个对象, 遍历第$() 两个参数,根据键名和键值,添加属性或者内容 ---> $(‘<div>1234‘,{id: ‘id‘, html: ‘123‘}) *若match数组有第三位值,根据元素的getElementById方法选择dom,包装成jQuery对象 (4) 否则如果match数组为空,且$()没有第二个参数,或者第二个参数为jQuery的时候,--->$(‘li‘) / $(‘li‘, $(‘ul‘))    在document或者第二个参数下,根据$(xxx).find()方法寻找这个字符串。 (5) 如果match数组为空,且$()第二个参数为字符串或者原生的dom的时候, ---> $(‘li‘,‘ul‘) / $(‘li‘, dom) 调用自身的init方法,把第二个参数包装成jQuery对象,在这个对象下面根据$(xxx).find()方法寻找这个字符串 3. 如果 $() 中第一个参数传递的是原生的dom节点,直接包装成jQuery对象 ---> $(this) // 通过nodetype来判断是不是dom 4. 如果 $() 第一个参数的传递的是一个函数,将参数传递给document.ready() 5. 如果什么也不是,就包装成一个数组返回。

  extend方法:

   该方法用来向jQuery原型上面或者jQuery对象上面添加方法,没有形参,方法根据传入的参数来判断进行了什么操作。

   这个函数本质是合并对象的方法,只是当只传一个对象的时候就合并到jQuery对象或者jQuery原型上面去了。并且根据第一个参数的boolean值来确定是通过深度克隆还是浅克隆来实现合并过程。

   这个方法同时定义在jQuery和jQuery.fn(即jQuery.prototype)上面   

jQuery.extend = jQuery.fn.extend = function(){
      //...        
}
 1. 当参数中只有一个对象的时候
   (1).如果第一个参数是true(默认是false并且不写)那么合并操作的目标对象就是this并且实现了深克隆(这里调用这个方法的可以是jQuery.fn或者jQeury)。
   (2).如果第一个参数没有传,那么合并操作的的目标对象是this并且是浅克隆。
        jQuery和jQuery.fn上面都定义了extend方法,这里通过函数内部this来区分是向那个对象中添加方法
 2. 如果参数中有多个对象
   (1). 我们选取第一个对象为合并操作的目标对象(当第一个对象是boolean(默认是false并且可以不写)),后面的对象依次向该对象中合并键值对
       ①. 第一个参数为true的时候,采用深克隆
       ②. 第一个是对象(或者false)的时候,采用浅克隆

    (源码的判断方式并非如此,这只是个人觉得好理解的方式)

    深克隆:  

        function deepClone(target, origin){
            var target = target || {};
            for(prop in origin){
                if(origin.hasOwnProperty(prop)){
                    if (typeof origin[prop] === ‘object‘) {
                        target[prop] = (Object.prototype.toString.call(origin[prop]) === ‘[Array object]‘ ?
                            [] : {});
                        deepClone(target[prop], origin[prop]);
                    } else {
                        target[prop] = origin[prop];
                    }
                }
            }
            return target;
        }

  

  

 

  

 

 

 

 

 

 

 

 

 

 

    

以上是关于?理解jQuery的主要内容,如果未能解决你的问题,请参考以下文章

markdown 在WordPress中使用jQuery代码片段

使用 NodeJS 和 JSDOM/jQuery 从代码片段构建 PHP 页面

很实用的JQuery代码片段(转)

几个有用的JavaScript/jQuery代码片段(转)

几个非常实用的JQuery代码片段

高效Web开发的10个jQuery代码片段