• JQuery源码分析(四)


    jQuery多库共存处理

    多库共存换句话说可以叫无冲突处理。

    总的来说会有2种情况会遇到:

       1、$太火热,jQuery采用$作为命名空间,不免会与别的库框架或者插件相冲突。

       2、jQuery版本更新太快,插件跟不上,导致不同版本对插件的支持度不一样。

    出于以上的原因,jQuery给出了解决方案–– noConflict函数。

    引入jQuery运行这个noConflict函数将变量$的控制权让给第一个实现它的那个库,确保jQuery不会与其他库的$对象发生冲突。

    在运行这个函数后,就只能使用jQuery变量访问jQuery对象。例如,在要用到$("aaron")的地方,就必须换成jQuery("aaron"),因为$的控制权已经让出去了。

    使用DEMO:

    jQuery.noConflict();
    // 使用 jQuery
    jQuery("aaron").show();
    // 使用其他库的 $()
    $("aaron").style.display = ‘block’;
    

     这个函数必须在你导入jQuery文件之后,并且在导入另一个导致冲突的库之前使用。当然也应当在其他冲突的库被使用之前,除非jQuery是最后一个导入的

    由于比较简单,我们直接上代码解说:

    Var _jQuery = window.jQuery,
        _$ = window.$;
    
    jQuery.noConflict = function( deep ) {
        if ( window.$ === jQuery ) {
            window.$ = _$;
        }
    if ( deep && window.jQuery === jQuery ) {
            window.jQuery = _jQuery;
        }
        return jQuery;
    };
    

     如果我们需要同时使用jQuery和其他JavaScript库,我们可以使用 $.noConflict()把$的控制权交给其他库。

    旧引用的$ 被保存在jQuery的初始化; noConflict() 简单的恢复它们。
        通过类似swap交换的概念,先把之前的存在的命名空间给缓存起来,通过对比当前的命名空间达到交换的目的,

    首先,我们先判断下当前的的$空间是不是被jQuery接管了,如果是则让出控制权给之前的_$引用的库,

    如果传入deep为true的话等于是把jQuery的控制权也让出去了。
        如果不通过noConflict处理的话其后果可想而知,

    <!DOCTYPE HTML>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <script src="http://img.mukewang.com/down/540812440001e40e00000000.js" type="text/javascript"></script>
    <title>多库共存</title>
    </head>
    <body>
        
    <div id="aaron">测试noConflict效果</div>
    
    <script type="text/javascript">
    
        $("#aaron").click(function() {
    
            $.noConflict(); //让出控制权
    
    		if (!$) {
    			show("使用noConflict后,$不存在")
    		}
    
    		if (jQuery) {
    			show("使用noConflict后,jQuery存在")
    		}
    
    		//通过闭包隔离出$
    		;(function($) {
    			if ($) {
    				show("通过闭包隔离后,转为局部变量$存在")
    			}
    		})(jQuery);
    
        })
    
        function show(data) {
        	jQuery("body").append('<li>' + data + '</li>')
        }
    
    </script>
    </body>
    </html>
    

    JQuery核心模块:

    对象的构建

    面向对象(OOP)的语言都有一个特点,它们都会有类的这一概念,通过类可以抽象出创建具体相同方法与属性的对象。

    但是ECMAScript中是没有类的概念的,因此它的对象与基于类的语言如java的定义是有所不同的。

    在JavaScript世界中函数作为“一等公民”,它不仅拥有一切传统函数的使用方式(声明和调用),

    而且可以做到像简单值一样赋值、传参、返回,这样的函数也称之为第一级函数。不仅如此,而且还可以通过操作符new来充当类的构造器。

    函数在充当类的构造器时,原型prototype是一个重要的概念。prototype是构造函数的一个属性, 该属性指向一个对象。

    而这个对象将作为该构造函数所创建的所有实例的基引用(base reference), 可以把对象的基引用想像成一个自动创建的隐藏属性。

    当访问对象的一个属性时, 首先查找对象本身, 找到则返回;若不, 则查找基引用指向的对象的属性(如果还找不到实际上还会沿着原型链向上查找,  直至到根)。

    只要没有被覆盖的话, 对象原型的属性就能在所有的实例中找到。

    类一:

    function ajQuery() {
        this.name = 'jQuery';
        this.sayName = function(){
        return this.name
    }
    var a = new ajQuery()
    var b = new ajQuery()
    var c = new ajQuery()
    

     类二:

    function ajQuery() {
        this.name = 'jQuery'
    }
    ajQuery.prototype = {
        sayName: function() {
        return this.name
        }
    }
    var a = new ajQuery()
    var b = new ajQuery()
    var c = new ajQuery()
    

    类一与类二产生的结构几乎是一样的,而本质区别就是:类二new产生的a、b、c三个实例对象共享了原型的sayName方法,

    这样的好处节省了内存空间,类一则是要为每一个实例复制sayName方法,每个方法属性都占用一定的内存的空间,

    所以如果把所有属性方法都声明在构造函数中,就会无形的增大很多开销,这些实例化的对象的属性一模一样,都是对this的引用来处理。

    除此之外类一的所有方法都是拷贝到当前实例对象上。类二则是要通过scope连接到原型链上查找,这样就无形之中要多一层作用域链的查找了。

    jQuery对象的构建如果在性能上考虑,所以就必须采用原型式的结构:

    jQuery = function( selector, context ) {
        return new jQuery.fn.init( selector, context );
    }
    jQuery.fn = jQuery.prototype = {
        init:function(){
        return this
    },
        jquery: version,
        constructor: jQuery,
        ………………
    }
    var a = $() ;
    

    使用原型结构,性能上是得到了优化,但是ajQuery类这个结构与目标jQuery的结构的还是有很大不一致:

       没有采用new操作符;

       return返回的是一个通过new出来的的对象 。

    <!DOCTYPE HTML>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <script src="http://img.mukewang.com/down/540812440001e40e00000000.js" type="text/javascript"></script>
    <script src="http://img.mukewang.com/down/541f6ff70001a0a500000000.js" type="text/javascript"></script>
    <title></title>
    </head>
    <body>
        
    <div id="aaron"></div>
    
    <script type="text/javascript">
    
    //类一:
    function ajQuery() {
      this.name = 'jQuery';
      this.sayName = function() {
        return this.name
      }
    }
    var a = new ajQuery()
    var b = new ajQuery()
    var c = new ajQuery()
     
    
     
    // 类二
    function ajQuery() {
        this.name = 'jQuery'
    }
    ajQuery.prototype = {
        sayName: function() {
        return this.name
        }
    }
    var a = new ajQuery()
    var b = new ajQuery()
    var c = new ajQuery()
    
    
    // jQuery的写法
    var $jQuery = function(selector, context) {
      return new $jQuery.fn.init(selector, context);
    }
    
    $jQuery.fn = $jQuery.prototype = {
      init: function() {
        this.name = 'aaron'
        return this;
      },
      constructor: $jQuery
    }
    
    var $a = $jQuery();
    
    show('$jQuery的调用')
    show($a);
    
    </script>
    </body>
    </html>
    
  • 相关阅读:
    js总结 (1)数据类型以及转换的知识整理
    伪元素 hover 的几种用法总结
    一套网页 同时适配pc端和移动端的布局思路(不要怕固定定位 和百分比)
    移动端 高亮小知识 -webkit-tap-highlight-color:transparent; tap-highlight-color:transparent;
    移动端布局 viewport 用法 简单总结
    Linux系统登陆成功和登陆失败日志的查看
    Windows系统ntlm哈希与解密、本地RDP连接密码获取
    office小技巧和一些奇怪问题的汇总解决
    阿里云镜像导出至本地操作
    sqlite数据库文件的打开与读取
  • 原文地址:https://www.cnblogs.com/sunliyuan/p/6063285.html
Copyright © 2020-2023  润新知