模拟jQuery底层源码的链式调用和常用的$()方法的实现

最近在看jQuery框架的源码,感觉还是学到不少东西的,所以就想总结一下自己的知识,和广大的前端爱好者一起

交流一下,我下面所说的并不是直接对jQuery的源码来解读,我是模拟一下jQuery底层源码的链式调用大概是怎么

实现的和常用的$功能是怎么实现的。好了废话不多说了。
你要看这个,你就要对jQuery有一定的了解,最起码你要用过jQuery。
首先看下jQuery的源码开始是怎么写的

(function( window, undefined){
    
})(window);
它的代码就是被这个块级作用域包裹着,
这里我有必要说一下块级作用域
(function(){
    //这就是一个最简单的块级作用域
    //特点1:程序启动的时候,里面的代码就直接执行了
    alert(‘我执行了‘);  //我执行了
    //特点2:内部的成员变量,外部是无法访问,(除了不加var的变量)
    var a =10;
})();
alert(a);   //a is not defined

上面,我们了解了块级作用域的概念了,也就明白了
里面的成员和方法是不可以被外界所调用的,
但是jQuery不是一开始就可以用$这个功能吗
(function( window, undefined){
    //里面的代码,就要把$返回给外界
})(window); //window相当于程序的入口,把参数window传入作用域中

好了,我们下面就开始说下jQuery了
(function(window,undefined){
    //在大型程序开发中,一般使用‘_‘作为私有的对象
    function _$(arguments){
        
    };
    //window上先注册一个全局变量,与外界产生关系
    window.$ = _$;
    //写一个准备的方法
    _$.onReady = function(fn){
        fn();   //11
    };
})(window);
//jQuery的调用一般这样写
$.onReady(function(){
    alert(11);
});
//这样就实现了$.onReady这个方法了
但是这样还不是很合理,我们还要完善一下
(function(window,undefined){
    //在大型程序开发中,一般使用‘_‘作为私有的对象
    function _$(arguments){
        
    };
    
    //_$这是个类,也是一个函数,所以 也属于Function
    Function.prototype.method = function(methodName,fn){
        this.prototype[methodName] = fn;
        //实现链式编程的关键
        return this;
    };
    
    //在_$的原型对象中加一些公共的方法
    _$.prototype ={
        //还原构造器
        constructor:_$,
        //添加事件方法
        addEvent:function(){
            alert(‘addEvent‘);
            //这里才是我们真正实现具体方法的链式编程
            return this;
        },
        //改变样式
        setStyle:function(){
            alert(‘setStyle‘);
            //这里才是我们真正实现具体方法的链式编程
            return this;
        }
    };
    //window上先注册一个全局变量
    window.$ = _$;
    //写一个准备的方法
    _$.onReady = function(fn){
        //1实例化_$对象,真正的注册到window上
        window.$ = function(){
            return new _$(arguments);
        };
        //2执行传入的代码
        fn();
        //实现链式编程
        //我们知道链式编程的写法:$().method1().method2();
        _$.method(‘addEvent‘,function(){
            
        }).method(‘setStyle‘,function(){
            
        });
    };
})(window);
//jQuery的调用一般这样写
$.onReady(function(){
    $().addEvent().setStyle(); //addEvent setStyle
});
这时候我们已经大概写完了程序,就差一些具体的方法还没有实现而已

上面已经实现程序的总体框架已搭建完成了,下面我会把所有的代码写上
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<input id="inp" type="button" value="点击"/>
<script type="text/javascript">
(function(window,undefined){
    //在大型程序开发中,一般使用‘_‘作为私有的对象
    function _$(arguments){
        //正则表达式用于判断是否为ID选择器
        var idselector = /#\w+/;
        //正则表达式匹配class选择器
        var classSelector = /\.\w+/;
        //加一个属性,用于接受所得到的元素
        this.dom;
        //test的用处
        //1通过该值可以匹配字符串中是否存在于正则表达式相匹配的结果
        //2返回值是布尔值,匹配为true,反之为false
        if(idselector.test(arguments[0])){
            if(typeof arguments[0] === ‘string‘){
                //因为document.getElementById("ID") 获取元素
                //id是不带#
                var itemId = arguments[0].substring(1);
                this.dom = document.getElementById(itemId);
            }else{
                throw new Error(‘arguments is error‘);
            }
        }else if(classSelector.test(arguments[0])){
            
        }else{
            //都不匹配就抛个错误
            throw new Error(‘arguments is error‘);
        }
    };
    
    //_$这是个类,也是一个函数,所以 也属于Function
    Function.prototype.method = function(methodName,fn){
        this.prototype[methodName] = fn;
        //实现链式编程的关键
        return this;
    };
    
    //在_$的原型对象中加一些公共的方法
    _$.prototype ={
        //还原构造器
        constructor:_$,
        //添加事件方法
        addEvent:function(type,fn){
            //给你得到的元素注册事件,要判断浏览器类型
            if(window.addEventListener){ //FF
                this.dom.addEventListener(type,fn);
            }else if(window.attachEvent){ //IE
                this.dom.attachEvent(‘on‘+type,fn);
            }
            //这里才是我们真正实现具体方法的链式编程
            return this;
        },
        //改变样式
        setStyle:function(prop,val){
            this.dom.style[prop] = val;
            //这里才是我们真正实现具体方法的链式编程
            return this;
        }
    };
    //window上先注册一个全局变量
    window.$ = _$;
    //写一个准备的方法
    _$.onReady = function(fn){
        //1实例化_$对象,真正的注册到window上
        window.$ = function(){
            return new _$(arguments);
        };
        //2执行传入的代码
        fn();
        //实现链式编程
        //我们知道链式编程的写法:$().method1().method2();
        _$.method(‘addEvent‘,function(){
            
        }).method(‘setStyle‘,function(){
            
        });
    };
})(window);
//jQuery的调用一般这样写
$.onReady(function(){
    //我们平常都是这样写的
    $(‘#inp‘).addEvent(‘click‘,function(){
        alert(‘我被点击了‘);
    }).setStyle(‘backgroundColor‘,‘red‘);

});
//这样就实现了$.onReady这个方法了

</script>
</body>
</html>

本人才疏学浅,如若有不正确的地方,请大家指出,我会努力改过的。

时间: 2024-10-05 18:16:25

模拟jQuery底层源码的链式调用和常用的$()方法的实现的相关文章

【深入浅出jQuery】源码浅析2--奇技淫巧

最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐进增强)优雅的处理能力以及 Ajax 等方面周到而强大的定制功能无不令人惊叹. 另外,阅读源码让我接触到了大量底层的知识.对原生JS .框架设计.代码优化有了全新的认识,接下来将会写一系列关于 jQuery 解析的文章. 我在 github 上关于 jQuery 源码的全文注解,感兴趣的可以围观一下

jQuery.access源码分析

基本理解 jQuery.attr是jQuery.attr,jQuery.prop,jQuery.css提供底层支持,jQuery里一个比较有特色的地方就是函数的重载, 比如attr,有如下几种重载 $('#box').attr('title') $('#box').attr('title','标题') $('#box').attr({title:'标题',data-menu-toggle:'dropdown'}) $('#box').attr('title',function () {....}

jQuery.attributes源码分析(attr/prop/val/class)

回顾 有了之前的几篇对于jQuery.attributes相关的研究,是时候分析jQuery.attr的源码了 Javascript中的attribute和property分析 attribute和property兼容性分析 jQuery.access源码分析 结构 jQuery.fn.extend({ attr: function (name, value) { }, removeAttr: function (name) { }, prop: function (name, value) {

jQuery选择器源码分析和easyui核心分析

写在选择器源码分析之前 这里指对1.7.2版本的源码分析,更高版本添加了更多代码. 整个jQuery的代码是写在一个(function(window, undefined){})(window);这样一个闭包里.请思考,为什么要这样做? 将其写在一个闭包函数里,并传入window直接运行的好处有三: 1,统一命名空间,防止变量的污染:  2,将window作为参数传入函数,在函数里调用window的时候,就不用再去找外层的对象,可以提高效率 : 3,undefined并不是javascript的

自写图片遮罩层放大功能jquery插件源码,photobox.js 1.0版,不兼容IE6

阿嚏~~~ 话说本屌丝没啥开发插件的经验,但是天公不作美,公司需要让我自己开发个图片放大的插件 但公司老大的话,犹如吾皇之圣旨,微臣必当肝脑涂地,莫敢不从啊~~~ 于是乎,作为一个超级小白,本人只能瞎研究了,幸好黑天不负屌丝人,本屌丝终于搞出来了,虽然不尽善尽美,但是功能还是可以用的啦 先附上源码,求各种大神指导: /******************************* * photobox跨浏览器兼容插件 v1.0(不支持IE6) * 格式:<a href="big.jpg&q

jQuery方法源码解析--jQuery($)方法(一)

jQuery方法源码解析--jQuery($)方法 注: 1.本文分析的代码为jQuery.1.11.1版本,在官网上下载未压缩版即可 2.转载请注明出处 jQuery方法: 这个方法大家都不陌生,在使用过程中,它还有另外一个名字,美元符号:$,$(...)其实就是jQuery(...); 它有很多种用法,通常都返回一个jquery对象,也可以作为$(document).ready(...);的简写形式,分析之前先看一下jQuery都有什么用法. 1.jQuery( selector [, co

模拟银行输入密码源码+注释+解答!

这篇文章是个大家分享的一点小知识:模拟银行输入密码源码+注释+解答! //模拟密码的输入 //库1 :*** //库2 :到位数 自动提交 //网络api 细节 800页 //学习网络概念 库 //c 数据结构 linux //C++ 数据结构 windows qt mfc //8000 #include #include #include //getch 没有回显 getchar回显 int main() { char passwd[] = "123456"; //原始密码 char

C语言教程 模拟银行输入密码源码

这篇文章是个大家分享的一点小知识:模拟银行输入密码源码+注释+解答! //模拟密码的输入 //库1 :*** //库2 :到位数 自动提交 //网络api 细节 800页 //学习网络概念 库 //c 数据结构 linux //C++ 数据结构 windows qt mfc //8000 #include #include #include //getch 没有回显 getchar回显 int main() { char passwd[] = "123456"; //原始密码 char

2018.11.20 Struts2中对结果处理方式分析&amp;struts2内置的方式底层源码剖析

介绍一下struts2内置帮我们封装好的处理结果方式也就是底层源码分析 这是我们的jar包里面找的位置目录 打开往下拉看到result-type节点 name那一列就是我们的type类型取值 上一篇博客在分析的时候发现就算不写也会自动转发原因在这里,default=true 选择了默认方式 接着我们如果想看看底层是如何工作的就选择class属性复制双引号的内容 接着按住ctrl+shift+T就能出现一个框 OPen Type 进去之后发现是这个,点击Attach Source---->选择第二