zoukankan      html  css  js  c++  java
  • jQuery的XX如何实现?——1.框架

    源码链接:内附实例代码

    jQuery使用许久了,但是有一些API的实现实在想不通。于是抽空看了jQuery源码,现在把学习过程中发现的一些彩蛋介绍给大家(⊙0⊙)。

    下面将使用简化的代码来介绍,主要关注jQuery的实现思想~>_<~

     1 //匿名立即执行函数
     2 //1.防止污染全局空间
     3 //2.选择性保护内部变量
     4 (function(window, undefined){
     5     //第二参数undefined设置而不传的原因:
     6     // 外部发生这种情况:var undefined = 10时,undefined会被篡改
     7     // 设置第二参数而不传,则undefined就会被重置回原来值
     8 
     9     function jQuery(sel){
    10         return new jQuery.prototype.init(sel);
    11     }
    12     
    13     jQuery.prototype = {
    14         constructor: jQuery,
    15         init: function(sel){
    16             if(typeof sel === 'string'){
    17                 var that = this;
    18                 //jQuery内部使用的是Sizzle,这里使用querySelectorAll替代
    19                 var nodeList = document.querySelectorAll(sel);
    20                 Array.prototype.forEach.call(nodeList, function(val, i){
    21                     that[i] = val;
    22                 })
    23                 this.selector = sel;
    24                 this.length = nodeList.length;
    25             }
    26         }
    27     }
    28     
    29     jQuery.prototype.init.prototype = jQuery.prototype;
    30     
    31     //对外暴露jQuery:将jQuery绑定在window上面
    32     window.$ = jQuery;
    33 })(window);

    --------------------------

    jQuery一开始使用匿名立即执行函数包裹其内部,并在第5行对外暴露;

    所谓的匿名立即执行函数即这个函数是匿名的(没有名字)、定义完后立即调用的;

    当我们在外部调用$("div")时,其实调用的就是内部的jQuery("div");

    (function(window, undefined){
      //内部变量
      
      //对外暴露jQuery:将jQuery绑定在window上面
      window.$ = jQuery;
    })(window);
    
    $("div")

    --------------------------

    好,接下来稍复杂点,下面的代码主要实现如图的互相引用:

    以$('div')调用为例: 

    从第2行代码可以看出,jQuery使用jQuery.prototype.init来实例化jQuery对象,但这会带来一个问题:

    实例化的对象只能访问到init下的变量,而不能访问到jQuery.prototype(jQuery对外提供的API绑定在该对象下)。

    于是乎,补写第21行代码,将init.prototype指向jQuery.prototype即可。

    这样就完成了,使用init来实例化,且可以在init作用域下访问到jQuery.prototype。

     1 function jQuery(sel){
     2     return new jQuery.prototype.init(sel);
     3 }
     4 
     5 jQuery.prototype = {
     6     constructor: jQuery,
     7     init: function(sel){
     8         if(typeof sel === 'string'){
     9             var that = this;
    10             //jQuery内部使用的是Sizzle,这里使用querySelectorAll替代
    11             var nodeList = document.querySelectorAll(sel);
    12             Array.prototype.forEach.call(nodeList, function(val, i){
    13                 that[i] = val;
    14             })
    15             this.selector = sel;
    16             this.length = nodeList.length;
    17         }
    18     }
    19 }
    20 
    21 jQuery.prototype.init.prototype = jQuery.prototype;

     为什么使用jQuery.prototype.init来实例化对象,而不直接使用jQuery函数呢?

    假设使用jQuery函数来实例化对象,这样对象之间的引用的确可以简化为 jQuery-->jQuery.prototype。

    但是调用会变得繁琐起来:new $('div'),所以基于这个考虑(猜测(⊙0⊙)),在内部使用较为复杂的实现,来简化调用。

    --------------------------

    好,最后,再来看一下init的实现。同样也简化了代码,只实现了最常用的一种情况。

    jQuery会把获取到的nodeList处理成数组(方便后续使用),并在其下挂载一些变量,如length,selector。

     1 init: function(sel){
     2     if(typeof sel === 'string'){
     3         var that = this;
     4         //jQuery内部使用的是Sizzle,这里使用querySelectorAll替代
     5         var nodeList = document.querySelectorAll(sel);
     6         Array.prototype.forEach.call(nodeList, function(val, i){
     7             that[i] = val;
     8         })
     9         this.selector = sel;
    10         this.length = nodeList.length;
    11     }
    12 }

    --------------------------

    下一期预告:jQuery的XX如何实现?——2.show与链式调用

    ps:代码已经上传到github中了

  • 相关阅读:
    免费下载小说
    前段博客云库网
    node发送邮件
    node 发送短信
    node生成uuid
    node 控制台颜色
    OfficeCommandbarDesigner20170202.rar
    OfficeCommandbarViewer20171005.rar
    VB.Net 正则表达式测试器
    Windows_Management_Instrumentation
  • 原文地址:https://www.cnblogs.com/jiahuix/p/5475146.html
Copyright © 2011-2022 走看看