jquery源码部分分析
1.整体架构和如何辨别浏览器端和node端
自执行函数,判断在什么端,如果在浏览器端就执行factory函数
//(function(){a,b})(a,b)
//jq大架构,闭包,自执行函数,传入函数参数(factory:工厂模式)
(function(global,factory){
"use strict" //严格模式
if(typeof module ==="object" && typeof module.exports ==="object"){
//说明支持CommonJS模块规范的(例如Node)
//...
}else{
//浏览器端
// factory(window) => 就是传入的函数参数执行 => function( window, noGlobal){
// window === window noGlobal === undefined(因为执行这个函数的时候,没有传第二个参数)
//}
factory(global);
}
})(typeof window !== "undefined" ? window : this ,function( window, noGlobal){
})
/*
参数一:
typeof window !== "undefined" ? window : this
区分在浏览器端运行还是Node端运行
typeof xx 如果xx不存在,不会报错,而是返回undefined(js中的暂时性死区问题)
typeof window !== "undefined" 这个成立,则他在浏览器端或者webView端(浏览器端存在window),不存在说明是Node端运行,this代指当前Node模块
=>第一个参数就是让global知道是在什么端运行的
参数二:factory为一个函数
function( window, noGlobal){}
*/
2.factory函数
factory为自执行函数传入的参数,并且在判断为浏览器端后执行,并且传入window对象 factory(global)
(function(global,factory){
factory(global);
})
(typeof window !== "undefined" ? window : this ,function( window, noGlobal){
// $() jQ选择器
//因为window.jQuery = window.$ = jQuery,所以我们$()执行的就是这个函数
var jQuery = function(selector,context){
return new jQuery.fn.init(selector,context)
}
//---------------------------each
jQuery.fn.each =function (callback){
//jQuery.each(jQ实例,callback)
return jQuery.each(this.callback);
};
jQuery.each = function(obj,callback){
//obj可以是数组(类数组) 或者 对象 =>用来遍历它们
}
//-------------------------extend向jq和jq原型上扩展方法
//=>向原型扩展方法是给jq实例用的,一般应用于jq插件封装
//=>向jq对象中扩展的方法是为了完善类库
//$.fn.extend({}) $.fn.extend(true,{})
jQuery.extend = jQuery.fn.extend = function(){
}
//--------------------------jQuery是一个类,它的原型上放了好多属性和方法
jQuery.fn = jQuery.prototype = {
//保证原型对象上的构造函数完整性
constructor : jQuery,
//...
};
//init 也是一个类
//new jQuery.fn.init(selector,context) => $()选择器是创建这个类的一个实例,所以$()就可以调用init原型上的方法
//实例本应该指向init.prototype,但是我们让init.prototype =jQuery.prototype,所以最终类的init实例的__proto__指向的是jQuery.prototype,也就是类似于创建了一个jQ类的实例 => $()jQ选择器就是jQ类的一个实例,此实例可以调取JQ原型上的方法
var init = jQuery.fn.init=function(selector,context){
//....
}
init.prototype = jQuery.fn = jQuery.prototype;
//冲突处理的( noConflict无冲突) =>$.noConflict()
//一个项目中引入了多个类库,其中一个类库(例如:zepto)用的也是$=>$===Zepto,此时如果也导入了JQ,那么$到底代表谁就冲突了
//假设zepto先引入,jq后引入,我们就把$的使用权给zepto,然后函数中又return了jquery
//所以,如果有冲突的时候,我们可以 let j = $.noConflict(); 以后 j 就代替了$
var _jQuery = window.jQuery,
_$ = window.$;
jQuery.noConflict = function(deep){
if(window.$ === jQuery){
window.$ = _$;
}
if(deep && window.jQuery ===jQuery){
window.jQuery = _jQuery
}
return jQuery
}
//这里为factory的函数体
//如果是浏览器端运行,条件成立 !undefined
if(!nonoGlobal){
//把jQuery或者$暴露到全局对象中(这样当外部引用了jquery的时候,就可以直接调用里面定义的方法)
window.jQuery = window.$ = jQuery
}
})
//=>jQ选择器其实就是把jQuery方法执行
//$() =>function(selector,context){} 让他执行
//$('.box')获取当前页面中样式类为box的盒子(范围/上下文:整个页面)
//$('.banner .box')获取.banner的盒子后代为.box的盒子 => 等价于$('.box',document.getElementById('banner'))
选择器
$([selector])
[selector]支持三种类型
"string" => 基于css选择器获取元素 (底层都是使用正则来一点一点匹配的)
元素节点 => 把DOM元素转换为jQ对象 (jQ类的实例)
函数 => $(document).ready(函数)
1.传css选择器为常见用法
2.传节点,常用于将dom对象转换为jq对象,方便调用jq内置方法
let boxList = document.querySelectorAll('.box')
let $boxList = $(boxList) //转换为jq对象
let box1 = $boxList[0] //将jq对象转换为原生dom,jq对象
3.传函数常用于开头,代码都再传入的函数中编写
$(function(){
//等价于 $(document).ready(函数) 当整个页面的DOM结构加载完成
})
分析源码后的一些应用问题
//$('.box')每一次执行都是创建一个JQ的新实例(jQ对象)
// => $('.box') !== $('.box') 两个不同的实例,开辟了两个堆内存
let $box = $('.box');
$('.box').click(()=>{})
$('.box').addClass()
$('.box').fadeIn()
//这样虽然能实现效果但是,开辟了三个堆内存,消耗性能,所以我们应该尽量用一个变量来接收,用这个变量区操作属性
$box.click(()=>{})
$box.addClass()
$box.fadeIn()
//在控制台输出jQuery.fn可以查看原型上的方法,这些方法都可以被实例所调用(此时把jq看作一个类)
//获取一个实例,再使用dir查看
let $box = $('.box')
console.dir($box)
//但jq也是一个普通对象,再普通对象上也有很多方法,这些方法和实例没有直接的关系,基于$.xxx()调用,例如:$.Callbacks() 或者 $.ajax() 等
console.dir(jQuery)
---------------------------------------------------------
//向jquery原型中拓展方法
$.fn.extend({
aaa(){ console.log('a') }
})
------------------------------------------------------------
//each (当返回值为false的时候,结束循环,forEach不支持)
// => $.each($('.box'),function(){})
// 等价于$('.box').each(function(){})
$.each([10,20,30],function(item,index)=>{}) //不能用箭头函数,没有this
$.each({age:10,name:小黄},function(key,value){
//参数顺序和数组的forEach是相反的
//this => value
})
jquery源码部分分析的更多相关文章
- jQuery源码分析系列
声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://git ...
- jQuery源码学习感想
还记得去年(2015)九月份的时候,作为一个大四的学生去参加美团霸面,结果被美团技术总监教育了一番,那次问了我很多jQuery源码的知识点,以前虽然喜欢研究框架,但水平还不足够来研究jQuery源码, ...
- Jquery源码学习(第一天)
jQuery是面向对象的设计通过window.$ = window.jQuery = $; 向外提供接口,将$挂在window下,外部就可以使用$和jQuery $("#div1" ...
- jQuery源码 Ajax模块分析
写在前面: 先讲讲ajax中的相关函数,然后结合函数功能来具体分析源代码. 相关函数: >>ajax全局事件处理程序 .ajaxStart(handler) 注册一个ajaxStart事件 ...
- jQuery源码:从原理到实战
jQuery源码:从原理到实战 jQuery选择器对象 $(".my-class"); document.querySelectorAll*".my-class" ...
- 【菜鸟学习jquery源码】数据缓存与data()
前言 最近比较烦,深圳的工作还没着落,论文不想弄,烦.....今天看了下jquery的数据缓存的代码,参考着Aaron的源码分析,自己有点理解了,和大家分享下.以后也打算把自己的jquery的学习心得 ...
- 从jquery源码中看类型判断和数组的一些操作
在深入看jquery源码中,大家会发现源码写的相当巧妙.那我今天也通过几个源码中用到的技巧来抛砖引玉,希望大家能共同研究源码之精华,不要囫囵吞枣. 1.将类数组转化成数组 我想大家首先想到的方法是fo ...
- 读艾伦的jQuery的无new构建,疑惑分析——jquery源码学习一
背景: 有心学习jquery源码,苦于自己水平有限,若自己研究,耗时耗力,且读懂之日无期. 所以,网上寻找高手的源码分析.再经过自己思考,整理,验证.以求有所收获. 此篇为读高手艾伦<jQuer ...
- JQuery源码解析(一)
写在前面:本<JQuery源码解析>系列是基于一些前辈们的文章进行进一步的分析.细化.修改而写出来的,在这边感谢那些慷慨提供科普文档的技术大拿们. 要查阅JQ的源文件请下载开发版的JQ.j ...
随机推荐
- python数组冒号取值操作
1.冒号的用法 1.1 一个冒号 a[i:j] 这里的i指起始位置,默认为0:j是终止位置,默认为len(a),在取出数组中的值时就会从数组下标i(包括)一直取到下标j(不包括j) 在一个冒号的情况下 ...
- traceback说明
一:traceback说明 该模块提供了一个标准接口来提取,格式化和打印Python程序的堆栈跟踪.它完全模仿Python解释器在打印堆栈跟踪时的行为.当您想要在程序控制下打印堆栈跟踪时,这很有用. ...
- python上传文件接口
1.由于公司做接口测试,遇到了上传文件,一直搞了好久,原来是加了头部的原因def test_79(self): '''导入配置文件''' request = e['mysqlshujuku'] url ...
- Codeforces Round #619 (Div. 2) A. Three Strings
You are given three strings aa , bb and cc of the same length nn . The strings consist of lowercase ...
- ANSYS布尔运算APDL
目录 1.交运算 2.加运算 3.减运算 4.分割 5. 搭接 6. 互分 6.粘结 1.交运算 交运算的结果是由每个初始图元的共同部分,形成一个新的图元. 命令 功能 备注 LINL 线与线的交 A ...
- AngularJS学习:第一个demo
1. 引入angular.js 相应版本下载地址: https://code.angularjs.org/ 2. 编写html <!DOCTYPE html> <html> & ...
- Leetcode 12,452,455-贪心算法
Leetcode第12题,整数转罗马数字,难度中等 整个题目比较好理解,难度也不大,就算不过脑子,用一串if也基本上可以解决问题,比如 /** 执行用时:6ms,在所有 Java 提交中击败了52.6 ...
- phpsduty安装SSL证书,apache不能启动,解决方案
最近给客户开发微信小程序,因为本人也不太懂服务器的安装,(大神勿喷),顾个人一直使用的集成环境,原来一直是客户提供主机什么的,都是我们和客户说一下需要什么环境啊,配置啊,之类的,这次首次自己动手. 废 ...
- Ubuntu 16.04 安装Redis服务器端
~ sudo apt-get install redis-server 安装完成后,Redis服务器会自动启动,我们检查Redis服务器程序 检查Redis服务器系统进程 ~ ps -aux|grep ...
- 学习之学习--混沌大学商学院--第一课--HHR计划
<学习之学习> 第一课:混沌初开 李善友 1,课程目标:建立个人的多元思维模型,帮助企业找到创新驱动的增长战略. 2,创新:第二曲线创新,创新理论之父熊彼特. 3,核心课:第二曲线,非连续 ...