jQuery源码阅读笔记(1)

前言

本文是个人阅读源码、配合查找资料,将自己所见、所想记录下来的一些笔记

而主体是解析如何将部分方法实现,手动打造自己的jQuery

注:文本水平有限,并不谈论兼容性问题

正文

起步

(function (window, undefined) {
	var jQuery = function() {
        //...
    }
    //...
    window.jQuery = window.$ = jQuery;
})(window);

观察这一段则能知道:

  • jQuery本质是一个函数,这一点在导入了jQuery文件后,使用typeof检测jQuery或者$也能知道
  • 通过立刻调用函数执行后,将jQuery设置为window的属性,使得可以全局使用jQuery函数
  • 同时给$绑定函数引用,使操作更简洁

对参数的说明:

  • 减少作用域的查找,提高速度。后续还会多次看到这种操作
  • 利用自定义参数名,可以将关键词的长度缩短,在压缩代码时效果更明显
  • undefined参数是为了获取一个真实的undefined,因为undefined并非保留关键字,可以当作变量名,可以赋值,在低版本浏览器当中赋值会保留

个人的想法:

  • undefined参数使用场景并不知道在哪,哪个地方会直接用到undefiend这个值呢

  • 函数表示式是否可以直接写成函数声明。从简化的角度看,函数表达式多了var=

  • 对于立刻调用的匿名函数,是否可以将换成!形式触发

    • 小括号开头有一定风险,如果上一条语句没有以分号结束,且也是小括号或者方括号结尾,则会发生错误

    • 对于这一点,也可以在开头加上分号,不过就比较ugly

      !function(window){
         function jQuery(){}
         //...
      }(window);
      

为了更加简洁,后文无特殊说明的情况下,$表示jQuery

调用$()发生的事情

var jQuery = function(selector) {
    return new jQuery.fn.init(selector);
}
jQuery.fn = jQuery.prototype = {
    constructor: jQuery
}
jQuery.fn.init = function (selector) {
    //...
}
jQuery.fn.init.prototype = jQuery.fn;

一步步分析:

  • 获取的会是一个对象,此对象来自函数返回值
  • 而对象来自$原型上的一个函数,使用new创造的实例对象
  • 并不能返回函数本身的实例对象,这会导致无限递归
  • 此处就是为了省去手动使用new创造实例对象,使操作轻松便捷

其他事情:

  • 中间添加了一个fn属性,赋值为prototype,为的是将prototype关键字缩短,能少写些就少写些

  • 而赋值一个对象,是直接重写了prototype属性,可以在对象当中写好需要的实例方法与属性,而无需每个方法和属性前都加上prototype这么笨重的关键字

    init()可以写在当中,此处脱离出来方便观察,当然在官方源码当中也是如此

关于原型方法:

  • 写在原型上的方法,是提供给构造函数和实例对象使用的。不同的实例对象,共享同一个相同的方法和属性

  • 而在$当中,比如each方法,它是既有静态,又有实例。当然两者效果是一致的

  • 对此类方法的处理是,只添加一个静态方法,原型上再添加对静态方法的引用,也就是静态和实例共享一个方法

    //静态方法
    jQuery.each = function() {
        //.....
    }
    
    //实例方法
    jQuery.fn.each = function() {
        return jQuery.each();
    }
    
  • 当然,这里是往$的原型上添加方法,而我们获取的并不是$的实例对象,所以需要将两者的原型关联起来,于是就有这一步

    //左右顺序可不能颠倒
    jQuery.fn.init.prototype = jQuery.fn;
    
  • 因此,在写原型时将constructor: jQuery加入其中,将构造函数又指向了jQuery

    原型中的方法构造函数和实例对象都能访问,但是构造函数使用就需要加上prototype前缀

个人的想法:

  • 对于最后一步原型的调整,事实上我不太懂
  • 如果说原型方法是通过调用静态方法使用的,那我不是也可以直接通过initprototype来调用,也可以达到一样的效果。
  • 这一点我只能想到,为了简写,且能通过$查看prototype来知道有哪些方法
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值