jQuery源码学习(一)

jQuery的核心理念

  • 简洁的API
  • 优雅的链式
  • 强大的选择器
  • 便捷的操作

jQuery框架的核心就是从HTML文档中匹配元素并对其执行操作

jQuery源码整体放在一个匿名函数执行中

(function(window,undefined){//这里是形参
})(window,undefined);//传入实参

这样写的好处是:在匿名函数中定义的变量和函数在匿名函数外部都是访问不到的,在匿名函数中提供对外访问的接口

这里把window当做参数传进来是因为window处于作用域的最顶端,它的查找速度是最慢的。

好处1:将window作为实参传递给匿名函数的形参,在匿名函数中可以加快window的查找速度

好处2:在压缩版本中window作为实参传递给匿名函数的形参e,通过这样传递,我们知道在压缩代码中e就代表了window

传入undefined,是因为在匿名函数外部undefined可能被修改为其他值,将undefined作为参数传进来,在匿名函数中用到undefined了就是用的传进来的值而不会向外查找了。

方法和属性

jquery

用来输出相应的版本号:

<script type="text/javascript">
alert($().jquery);//弹出版本号
</script>

constructor

<script type="text/javascript">
function Person(){
}
Person.prototype.name = "lisi";
Person.prototype.age = 20;
var person1 = new Person();
alert(person1.constructor);//输出相应的构造函数
/*
function Person(){
}
 */
</script>
<script type="text/javascript">
function Person(){
}
Person.prototype = {//这里是重写了原型,这样构造函数指向就出现了问题,需要手动去修正
    constructor:Person,
    name:"lisi",
    age:20
}
var person1 = new Person();
alert(person1.constructor);
/*
function Object(){
    [native code]
}
 */
</script>

jQuery对象转为dom对象

<script type="text/javascript">
console.log($("li"));//jQuery.fn.init[3],每个li都有对应的下标
$("li")[1].style.background = "#f00";//$("li")[1]这样可以把jQuery转化为dom对象
</script>

parseHTML

jQuery.parseHTML用来将字符串转化为数组,返回一个数组

<script type="text/javascript">
$(function(){
    var str = ‘<li>1</li><li>2</li><li>3</li>‘;
    var arr = jQuery.parseHTML(str);
    console.log(arr);//[li, li, li]
    $.each(arr,function(i){
        $("ul").append(arr[i]);
    });
});
</script>

merge

script type="text/javascript">
$(function(){
    var arr1 = [‘a‘,‘b‘];
    var arr2 = [‘c‘,‘d‘];
    var arr3 = {
        0:‘a‘,
        1:‘b‘,
        length:2
    };
    //$.merge用来合并数组
    console.log($.merge(arr1,arr2));//["a", "b", "c", "d"]
    //$.merge也可以用来合并json
    //merge在jQuery中可以用来合并json
    console.log($.merge(arr3,arr2));//Object {0: "a", 1: "b", 2: "c", 3: "d", length: 4}
});
</script>

正则匹配

<script type="text/javascript">
    var rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/;
    var str1 = ‘#div1‘;
    var str2 = ‘<li>hello‘;
    console.log(rquickExpr.exec(str1));//["#div1",undefined,‘div1‘];
    console.log(rquickExpr.exec(str2));//["<li>hello", "<li>", undefined]
    </script>

makeArray

<body>
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <script type="text/javascript" src="../jquery-2.1.4.js"></script>
    <script type="text/javascript">
        var oDiv=document.getElementsByTagName("div");
        /*
        oDiv只是一个类数组,并不是真正的数组,类数组不能调用数组的方法
        在jQuery中可以通过makeArray方法将类数组转为真正数组
         */
        console.log(oDiv);//HTMLCollection[div, div, div]
        console.log($.makeArray(oDiv));//[div, div, div]  变为数组
         console.log($.makeArray(oDiv,{length:0}));// Object { 0=div,  1=div,  2=div,  更多...}   变为json形式
    </script>
</body>

pushStack

    pushStack():JQ对象的入栈
    栈是后进先出,所以这里span的背景颜色变红
    队列是先进先出
    end() 进行出栈操作,来返回栈中的前一个状态
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>pushStack</title>
</head>
<body>
    <div>1111111</div>
    <span>222222</span>
    <script type="text/javascript" src="../jquery-2.1.4.js"></script>
    <script type="text/javascript">
$(function(){     $(‘div‘).pushStack($(‘span‘)).css(‘background‘,‘red‘);
//end() 进行出栈操作,来返回栈中的前一个状态,所以div背景变黄了
          $(‘div‘).pushStack($(‘span‘)).css(‘background‘,‘red‘).end().css(‘background‘,‘yellow‘);
        });
    </script>
</body>
</html>
<body>
    <div>1111111</div>
    <div>1111111</div>
    <div>1111111</div>
    <div>1111111</div>
    <span>222222</span>
    <script type="text/javascript" src="../jquery-2.1.4.js"></script>
    <script type="text/javascript">
        $(function(){
            //$(‘div‘).slice(1,3).css(‘background‘,‘red‘);
//$(‘div‘)选择了所有的div
//slice(1,3)选择了中间两个div
//栈中$(‘div‘)在下,slice(1,3)在上
//所以css(‘background‘,‘red‘)使得中间两个div背景变红
//end() 进行出栈操作,返回栈中的前一个状态
//css(‘color‘,‘blue‘)使得四个div的字体颜色都为蓝色
            $(‘div‘).slice(1,3).css(‘background‘,‘red‘).end().css(‘color‘,‘blue‘);
        });
    </script>
</body>

map

返回新集合

<body>
    <script type="text/javascript" src="../jquery-2.1.4.js"></script>
    <script type="text/javascript">
        var arr=[‘a‘,‘b‘,‘c‘];
        //将原始数组中的每个值加上自己索引后,映射到新的数组中。
        arr=$.map(arr,function(elem,i){
            //i是数组元素的下标
            //elem表示数组元素
            return elem+i;
        });
        console.log(arr);// ["a0", "b1", "c2"]
    </script>
</body>

eq

first(就是eq(0))和last(就是eq(-1))方法都是基于eq方法来实现的

<body>
    <div>1111111</div>
    <div>1111111</div>
    <div>1111111</div>
    <div>1111111</div>
    <span>222222</span>
    <script type="text/javascript" src="../jquery-2.1.4.js"></script>
    <script type="text/javascript">
        /*
        eq是获取指定下标的元素
        下标可以为负值
         */
        $(function(){
            //$(‘div‘)选择了所有的div
            //eq(2)选择了第三个div
            //栈中$(‘div‘)在下,eq(2)在上
            //所以css(‘color‘,‘red‘)使得第三个div字体颜色变红
            $(‘div‘).eq(2).css(‘color‘,‘red‘);
            $(‘div‘).eq(-1).css(‘color‘,‘red‘);//其实是-1+length
        });
    </script>
</body>

toArray()

toArray()方法用来转数组

<body>
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <script type="text/javascript" src="../jquery-2.1.4.js"></script>
    <script type="text/javascript">
        $(function(){
            console.log($(‘div‘));//Object[div, div, div]  返回的是对象
            console.log($(‘div‘).toArray());//[div, div, div]  返回数组
        });
    </script>
</body>

extend–JQ的继承方法

jQuery.extend和jQuery.fn.extend

  • jQuery.extend 对jQuery本身的属性和方法进行了扩展
  • jQuery.fn.extend 对jQuery.fn的属性和方法进行了扩展

jQuery.extend 调用的时候,this是指向jQuery对象的(jQuery是函数,也是对象!),所以这里扩展在jQuery上。

而jQuery.fn.extend 调用的时候,this指向fn对象,jQuery.fn 和jQuery.prototype指向同一对象,扩展fn就是扩展jQuery.prototype原型对象。这里增加的是原型方法,也就是对象方法了。

<body>
<script type="text/javascript" src="../jquery-2.1.4.js"></script>
<script type="text/javascript">
    //当只写一个对象字面量的时候,JQ中扩展插件的形式
    $.extend({//扩展工具方法
        aaa:function(){
            alert(1);
        },
        bbb:function(){
            alert(2);
        }
    });
    $.fn.extend({//扩展JQ实例方法
        aaa:function(){
            alert(3);
        },
        bbb:function(){
            alert(4);
        }
    });
//$代表函数
$.aaa();
$.bbb();
//$()代表对象
$().aaa();
$().bbb();

//$.extend();   this指向$    this.aaa->$.aaa()
//$.fn.extend();   this指向$.fn     this.aaa->$().aaa()
//$.fn是原型,在原型下扩展的方法,需要通过对象实例来调用
</script>
</body>
<body>
<script type="text/javascript" src="../jquery-2.1.4.js"></script>
<script type="text/javascript">
    //当写多个对象字面量的时候,后面的对象都是扩展到第一个对象身上
    var a={};
    $.extend(a,{name:‘hello‘},{age:30});
    console.log(a);// Object { name="hello",  age=30}
</script>
</body>
<body>
<script type="text/javascript" src="../jquery-2.1.4.js"></script>
<script type="text/javascript">
    //当写多个对象字面量的时候,后面的对象都是扩展到第一个对象身上

    //还可以做深拷贝和浅拷贝
    //默认是浅拷贝
    var a={};
    var b={name:"hello"};
    $.extend(a,b);//浅拷贝
    a.name=‘hi‘;
    console.log(b.name);//hello

    //当进行浅拷贝的时候b.name.age会受影响,这时就需要深拷贝
    var a={};
    var b={name:{age:30}};
    $.extend(a,b);//浅拷贝
    a.name.age=20;
    console.log(b.name.age);//20

    var a={};
    var b={name:{age:30}};
    $.extend(true,a,b);//深拷贝
    a.name.age=20;
    console.log(b.name.age);//30
    /*
    JQ:拷贝继承
     */
</script>
</body>

jQuery.extend()–扩展一些工具方法

noConflict()

jQuery与其他库的防冲突解决

<body>
<div>1111111</div>
<script type="text/javascript" src="../jquery-2.1.4.js"></script>
<script type="text/javascript">
    var aa = $.noConflict();
    var $ = 123;
    aa(function(){
        alert($);//123
    });
</script>
</body>

在jQuery库之前引用$和jQuery

<body>
<script type="text/javascript">
/*
源码中:
_jQuery = window.jQuery
_$ = window.$
 */
//这里在引入jQuery之前将$赋值为123
//相当于将jQuery源码中的_$ = window.$ = 123
    var $ = 123;
//相当于将jQuery源码中的_jQuery = window.jQuery = 456
    var jQuery = 456;
    //console.log("window:"+window.$);//window:123
</script>
<script type="text/javascript" src="../jquery-2.1.4.js"></script>
<script type="text/javascript">
    var aa = $.noConflict(true);
    aa(function(){
        alert($);//123
        alert(jQuery);//456
    });
</script>
</body>

jQuery在其他库之后引入

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>jQuery与其他库的冲突解决</title>
</head>
<body>
    <div id="box1">Test-prototype(将被隐藏)</div>
    <div id="box2">Test-jQuery(将被绑定单击事件)</div>
    <script type="text/javascript" src="http://apps.bdimg.com/libs/prototype/1.7.1.0/prototype.js"></script>
    <script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <script type="text/javascript">
        jQuery.noConflict();//将变量$的控制权移交给prototype.js
        jQuery(function(){//使用jQuery
            jQuery("#box2").click(function(){
                alert(jQuery(this).text())
            });
        });
        $("box1").style.display = ‘none‘;//使用prototype.js隐藏元素
        //这样就可以将jQuery函数作为jQuery对象的制造工厂
    </script>
</body>
</html>

自定义快捷方式

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>jQuery与其他库的冲突解决</title>
</head>
<body>
    <div id="box1">Test-prototype(将被隐藏)</div>
    <div id="box2">Test-jQuery(将被绑定单击事件)</div>
    <script type="text/javascript" src="http://apps.bdimg.com/libs/prototype/1.7.1.0/prototype.js"></script>
    <script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <script type="text/javascript">
        $j = jQuery.noConflict();//将变量$的控制权移交给prototype.js
        $j(function(){//使用jQuery
            $j("#box2").click(function(){
                alert($j(this).text())
            });
        });
        $("box1").style.display = ‘none‘;//使用prototype.js隐藏元素
        //这样就可以将jQuery函数作为jQuery对象的制造工厂
    </script>
</body>
</html>

如果不想给jQuery自定义备用名称,还想使用而不管其他库的()方法,同时又不想与其他库相冲突,我们可以这样来解决

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>jQuery与其他库的冲突解决</title>
</head>
<body>
    <div id="box1">Test-prototype(将被隐藏)</div>
    <div id="box2">Test-jQuery(将被绑定单击事件)</div>
    <script type="text/javascript" src="http://apps.bdimg.com/libs/prototype/1.7.1.0/prototype.js"></script>
    <script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <script type="text/javascript">
        jQuery.noConflict();//将变量$的控制权移交给prototype.js
        (function($){//定义匿名函数并设置形参$
            $(function(){//匿名函数内部的$均为jQuery
                $("#box2").click(function(){//继续使用$()方法
                alert($(this).text())
            });
            });
        })(jQuery);//执行匿名函数且传递实参jQuery
        $("box1").style.display = ‘none‘;//使用prototype.js隐藏元素
    </script>
</body>
</html>

jQuery在其他库之前引入

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>jQuery与其他库的冲突解决</title>
</head>
<body>
    <div id="box1">Test-prototype(将被隐藏)</div>
    <div id="box2">Test-jQuery(将被绑定单击事件)</div>
    <script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <script type="text/javascript" src="http://apps.bdimg.com/libs/prototype/1.7.1.0/prototype.js"></script>
    <script type="text/javascript">
    //jQuery库在其他库之前引入了,可以直接使用jQuery,无需调用jQuery.noConflict(),可以使用$()方法作为其他库的快捷方式
        jQuery(function(){//直接使用jQuery,无需调用jQuery.noConflict()
            jQuery("#box2").click(function(){
                alert(jQuery(this).text())
            });
        });
        $("box1").style.display = ‘none‘;//使用prototype.js隐藏元素
        //这样就可以将jQuery函数作为jQuery对象的制造工厂
    </script>
</body>
</html>

expando

expando用来生成一个随机字符串

在数据缓存、事件操作、aJax都用到这个来生成随机字符串

<body>
<script type="text/javascript" src="../../jquery-2.1.4.js"></script>
<script type="text/javascript">
//生成一个随机字符串
console.log($.expando);//jQuery214073688220245906
</script>
</body>

待续。。。

时间: 2024-11-10 07:15:55

jQuery源码学习(一)的相关文章

jquery源码学习

jQuery 源码学习是对js的能力提升很有帮助的一个方法,废话不说,我们来开始学习啦 我们学习的源码是jquery-2.0.3已经不支持IE6,7,8了,因为可以少学很多hack和兼容的方法. jquery-2.0.3的代码结构如下 首先最外层为一个闭包, 代码执行的最后一句为window.$ = window.jquery = jquery 让闭包中的变量暴露倒全局中. 传参传入window是为了便于压缩 传入undefined是为了undifined被修改,他是window的属性,可以被修

菜鸟的jQuery源码学习笔记(二)

jQuery对象是使用构造函数和原型模式相结合的方式创建的.现在来看看jQuery的原型对象jQuery.prototype: 1 jQuery.fn = jQuery.prototype = { 2 //成员变量和方法 3 } 这里给原型对象起了一个别名叫做jQuery.fn.要注意的是这个jQuery.fn可不是jQuery对象的属性,而是jQuery构造方法本身的属性,它是不会传给它所创建的对象的.如果你在控制台敲$().fn的话输出的结果会是undefined.接下来看看原型对象里面有些

jquery源码学习(一)core部分

这一部分是jquery的核心 jquery的构造器 jquery的核心工具函数 构造器 jQuery = function( selector, context ) { // The jQuery object is actually just the init constructor 'enhanced' // Need init if jQuery is called (just allow error to be thrown if not included) return new jQu

jquery源码学习(二)sizzle部分 【转】

一,sizzle的基本原理 sizzle是jquery选择器引擎模块的名称,早在1.3版本就独立出来,并且被许多其他的js库当做默认的选择器引擎.首先,sizzle最大的特点就是快.那么为什么sizzle当时其他引擎都快了,因为当时其他的引擎都是按照从左到右逐个匹配的方式来进行查找的,而sizzle刚好相反是从右到左找的. 举个简单的例子 “.a .b .c”来说明为什么sizzle比较快.这个例子如果按照从左到右的顺序查找,很明显需要三次遍历过程才能结束,即先在document中查找.a,然后

jquery源码学习-构造函数(2)

最近几天一直在研究jquery源码,由于水平太低看得昏头转向.本来理解的也不是很深刻,下面就用自己的想法来说下jquery是如何定义构造函数初始化的.如果有什么不对的地方,希望个位高手指出.  一般写构造函数如下 function Aaa(){} Aaa.prototype.init = function(){}; Aaa.prototype.css = function(){}; var a1 = new Aaa(); a1.init(); //初始化 a1.css(); jQuery写法如下

jquery源码学习-初始(1)

最近几天一直在研究jquery源码,由于水平太低看得昏头转向.本来理解的也不是很深刻,下面就用自己的想法来说下jquery是如何定义构造函数初始化的.如果有什么不对的地方,希望个位高手指出. 首先要了解下什么时候自执行匿名函数 ,它的用途就是 相当于创建一个命名空间,只要把自己所有的代码写在这个特殊的函数包装内,外部不能访问,除非你允许. 基本格式 (function(){ //代码 })(); (function(){ var a = 10; function $(){ alert(a); }

jQuery源码学习笔记:总体架构

1.1.自调用匿名函数: (function( window, undefined ) { // jquery code })(window); 这是一个自调用匿名函数,第一个括号内是一个匿名函数,第二个括号立即执行,传参是window. 1.为什么有自调用匿名函数? 通过定义匿名函数,创建了一个"私有"空间,jQuery必须保证创建的变量不能和导入它的程序发生冲突. 2.为什么传入window? 传入window使得window由全局变量变成局部变量,jQuery访问window时,

jQuery源码学习:常用正则表达式

常用的数字正则(严格匹配) 正则 含义 ^[1-9]\d*$ 匹配正整数 ^-[1-9]\d*$ 匹配负整数 ^-?[1-9]\d*$ 匹配整数 /^(([1-9]\d*)|(0+))$/; 匹配非负整数(正整数 + 0) ^-[1-9]\d*|0$ 匹配非正整数(负整数 + 0) /^(([1-9]\d*)|0)\.\d+$/ 匹配正浮点数 ^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ 匹配负浮点数 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\

jQuery源码学习笔记:构造jQuery对象

3.1源码结构: (function( window, undefined ) { var jQuery = (function() { // 构建jQuery对象 var jQuery = function( selector, context ) { return new jQuery.fn.init( selector, context, rootjQuery ); } // jQuery对象原型 jQuery.fn = jQuery.prototype = { constructor:

jQuery源码学习笔记:扩展工具函数

// 扩展工具函数 jQuery.extend({ // http://www.w3school.com.cn/jquery/core_noconflict.asp // 释放$的 jQuery 控制权 // 许多 JavaScript 库使用 $ 作为函数或变量名,jQuery 也一样. // 在 jQuery 中,$ 仅仅是 jQuery 的别名,因此即使不使用 $ 也能保证所有功能性. // 假如我们需要使用 jQuery 之外的另一 JavaScript 库,我们可以通过调用 $.noC