深入理解jQuery框架-框架结构
这是本人结合资料视频总结出来的jQuery大体框架结构,如果大家都熟悉了之后,相信你们也会写出看似高档的js框架;
jquery框架的总体结构
(function(w, undefined){
//定义一些变量和函数
var
//对外提供的接口
jQuery = function( selector, context ) {
return new jQuery.fn.init( selector, context, rootjQuery );
};
//结jQuery对象添加一些方法和属性
//jQuery的继承方法
//jQuery.extend 扩展一些工具的方法(静态方法) jQuery.trim();
//Sizzle 复杂选择器的实现
//Callbacks 回调对象--函数的统一管理
//Deferred 延迟对象,对异步的统一管理
//support 功能检测
//Data 数据缓存
//queue 队列管理
//Attribute 属性操作
//Event 事件处理
//DOM操作 添加删除、包装筛选等
//CSS操作
//提交的数据和ajax
//运动/动画 FX
//坐标和大小
//支持的模块化的模式
w.jQuery = w.$ = jQuery;
})(window);
jquery为什么要使用匿名函数来封装框架
阅读jquery源码,我们可以看出jquery使用的是匿名函数来封装框架,那么为什么要使用这种方式呢,又有什么好处?
1.什么是匿名函数?
// 匿名函数的写法
function(){
console.log("test");
} // 将变量赋值给一个匿名函数
var test = function(){
return 0;
}
console.log(test); //打印的是变量test,即函数
console.log(test()); //打印0,test + ()表示调用这个方法
2.匿名函数自调用的方式
匿名函数有两种调用方式,第一种是()()、第二种是 (())
// ()()调用方式
(function(){
console.log("匿名函数-自调用方法1");
})();
// (())调用方式
(function(){
console.log("匿名函数-自调用方法2");
}());
3.匿名函数传参
/*错误方式*/
(function(window){
console.log(window); //undefined
})(); /*正确方式*/
var jQuery;
(function(win, jQuery){
console.log(win); //
})(window, jQuery);
4.使用匿名函数对外提供一个接口
(function(w) {
var Person = function() {
this.name = "cxb";
this.talk = function() {
console.log("hello, I'm " + this.name);
}
}
w.Person = Person;
})(window)
var p = new Person();
console.log(p.name);
p.talk();
5.使用匿名函数的好处:
防止变量方法冲突 变量与方法是独立的,写在匿名函数的变量或函数属于局部的,不会受外面的干扰,也不会影响全局变量
(function(){
var a = 10;
var fun = function() {
console.log("fun method");
}
})();
console.log(a); //报错 undefined
fun(); //报错 fun is not a function
为什么可以直接使用jQuery 或 $为调用jquery方法?
对象创建的比较
创建对象方式一:
function Student() {
this.name = "cxb";
this.talk = function() {
return "我叫" + this.name;
}
}
var stu1 = new Student();
var stu2 = new Student();
创建对象方式二:
function Student() {
this.name = "cxb";
}
Student.prototype.talk = function() {
return "我叫" + this.name;
}
var stu1 = new Student();
var stu2 = new Student();
方式一与方式二产生的结构几乎是一样的,而本质区别就是:方式二new产生的二个实例对象共享了原型的talk方法,这样的好处节省了内存空间,方式一则是要为每一个实例复制talk方法,每个方法属性都占用一定的内存的空间,所以如果把所有属性方法都声明在构造函数中,就会无形的增大很多开销,这些实例化的对象的属性一模一样,都是对this的引用来处理。除此之外方式一的所有方法都是拷贝到当前实例对象上。方式二则是要通过scope连接到原型链上查找,这样就无形之中要多一层作用域链的查找了。
所以说在jQuery中,可以看到很多 jQuery.fn 这样的写法(事实上在jQuery中,使用jQuery.fn替换了jQuery.prototype)。
浅拷贝与深拷贝
1. js对象的浅拷贝
var a = [1,2,3];
var b = a;
var c = {name:"cxb", age:26};
var d = c;
console.log(a);
console.log(b);
console.log(c);
console.log(d);
[1, 2, 3]
[1, 2, 3]
Object {name: "cxb", age: 26}
Object {name: "cxb", age: 26}
b[2] = 5;
d.age = 20;
console.log(a);
console.log(b);
console.log(c);
console.log(d);
[1, 2, 5]
[1, 2, 5]
Object {name: "cxb", age: 20}
Object {name: "cxb", age: 20}
2.js数组的深拷贝
var arr1 = [1, 2, 3];
var arr2 = []; function deepCopy(arr1, arr2) {
for(var i=0; i<arr1.length; i++) {
arr2[i] = arr1[i];
}
}
deepCopy(arr1, arr2);
console.log(arr1);
console.log(arr2);
arr2[2] = 5;
console.log(arr1);
console.log(arr2);
[1, 2, 3]
[1, 2, 3]
[1, 2, 3]
[1, 2, 5]
3.js对象的深拷贝
function Parent() {
this.name = "李四";
this.age = 40;
this.talk = function() {
console.log("hello, I'm "+ this.name);
}
}
function Child() {
this.name = "张三";
this.age = 20;
this.sound = function() {
console.log("haha");
}
}
Child.prototype = new Parent();
var child = new Child();
for(var key in child) {
console.log(key);
}
4.hasOwnProperty来过滤原型链上的属性
for(var key in child) {
if(child.hasOwnProperty(key))
console.log(key);
}
5.完整clone一个对象的方法
var child = new Child();
var childObject = {};
for(var key in child) {
if(child.hasOwnProperty(key))
childObject[key] = child[key];
}
console.log(childObject.name);
console.log(childObject.age);
childObject.sound();
childObject.talk();
jQuery框架的实现原理
/******************** jQuery 框架部分 ************************/
(function(w, undefined){
//第一步:创建一个jQuery函数
var jQuery = function() {
//第四步:
return new jQuery.fn.init();
} //第三步:
jQuery.fn = jQuery.prototype; //是覆盖prototype jQuery.fn = {
//当创建了一个函数之后,js源码会自动生成 jQuery.prototype.constructor = jQuery;
//在jQuery中使用这个是为了防止恶意修改:如 jQuery.prototype.constructor = Array;
constructor : jQuery, init : function() {
return this;
},
};
jQuery.fn.init.prototype = jQuery.fn; //如果不使用这个,在第四步当中是无法使用new的 //第五步:使用extend将jQuery模块化(其实原码并不是这样的)这里使用了拷贝,关于拷贝请看 4.js浅拷贝与深拷贝
//好处:插件扩展时直接使用此方法
jQuery.fn.extend = jQuery.extend = function( ) { var target = this, source = arguments[0] || { } ;
for(var key in source) {
if(source.hasOwnProperty(key)) {
jQuery.fn[key] = jQuery[key] = source[key];
}
}
return target;
} //第六步:模块一
jQuery.fn.extend({ html : function() {}, text : function() {}, }); //第六步:模块二
jQuery.extend({ ajax : function() {
//处理json格式的参数及回调函数success,error
console.log("ajax method");
}, each : function() {},
}); //第二步:对外提供一个接口
w.jQuery = w.$ = jQuery; })(window); //测试1
jQuery.ajax(); //测试2:外部框架的扩展
/******************** 基于jQuery框架的ui框架部分 ************************/
(function(w, jQuery) {
//jQuery对象的方法扩展
jQuery.fn.extend({
drag : function() {
console.log("drag method");
}, dialog : function() {
console.log("dialog method");
},
});
//jQuery类的方法扩展
jQuery.extend({
tool : function() {
console.log("tool method");
},
//....
});
})(window, jQuery);
示例
<html lang="zh-CN">
<head>
<script>
(function(win, undefined){
var doc = win.document;
var loc = win.location;
var jQuery;
jQuery = function(selector, context){
return new jQuery.fn.init(selector, context);
}
var _jQuery = win.jQuery, _$ = win.$;
jQuery.fn = jQuery.prototype; jQuery.fn = {
constructor: jQuery,
init : function(selector, context){
if(selector.charAt(0)=="#"){
this.context = doc.getElementById(selector.substr(1));
}else if(selector.charAt(0)=="."){
this.context = doc.getElementsByName(selector.substr(1));
}else if(selector.charAt(0)==":"){
this.context = doc.getElementsByTagName(selector.substr(1));
}else{
this.context = doc.getElementsByTagName(selector);
}
return this;
}
}
jQuery.fn.init.prototype = jQuery.fn; jQuery.fn.extend = jQuery.extend = function() {
var target = this;
var source = agruments[0] || { };
for (var p in source) {
if (source.hasOwnProperty(p)) {
target[p] = source[p];
}
}
return target;
}
// 对象的方法
jQuery.fn.extend( {
val : function() {
if((typeof _value)=="undefined"){
return this.context.value;
}else if((typeof _value)=="string"){
return this.context.value=_value;
}
}, html : function() {}, text : function() {}, attr : function() {}, prop : function() {}, //... }); // CSS操作
jQuery.fn.extend( {
addClass : function() {}, removeClass : function() {}, css : function() {}, //...
}); // 插件扩展的方法
jQuery.extend( {
ajax: function() {}, each: function() {}, when: function() {}, //...
});
// 对外提供的接口,即使用$ 或 jQuery
win.jQuery = win.$ = jQuery; })(window); window.onload = function(){
var value = jQuery("#test").val();
console.log("------"+value);
}
</script>
</head> <body>
<input type="text" id="test" value="123456" />
</body>
</html>
深入理解jQuery框架-框架结构的更多相关文章
- 小谈Jquery框架
现在Jquery框架对于开发人员基本上是无人不知,无人不晓了,用起来十分的方便,特别是选择器十分强大,提高了我们的开发速度.但是好多人也只是停留在了会用的基础上,我个人觉得会用一个框架不算什么,只能说 ...
- Jquery框架
现在Jquery框架对于开发人员基本上是无人不知,无人不晓了,用起来十分的方便,特别是选择器十分强大,提高了我们的开发速度.但是好多人也只是停留在了会用的基础上,我个人觉得会用一个框架不算什么,只能说 ...
- jQuery源码逐行分析学习01(jQuery的框架结构简化)
最近在学习jQuery源码,在此,特别做一个分享,把所涉及的内容都记录下来,其中有不妥之处还望大家指出,我会及时改正.望各位大神不吝赐教!同时,这也是我的第一篇前端技术博客,对博客编写还不是很熟悉,美 ...
- jQuery框架-2.jQuery操作DOM节点与jQuery.ajax方法
一.jQuery操作DOM 内部插入操作: append(content|fn):向每个匹配的元素内部追加内容. prepend(content):向每个匹配的元素内部前置内容. 外部插入操作: af ...
- jQuery系列 第二章 jQuery框架使用准备
第二章 jQuery框架使用准备 2.1 jQuery框架和JavaScript加载模式对比 jQuery框架的加载模式 <script> window.onload = function ...
- 从零实现一个简易的jQuery框架之二—核心思路详解
如何读源码 jQuery整体框架甚是复杂,也不易读懂.但是若想要在前端的路上走得更远.更好,研究分析前端的框架无疑是进阶路上必经之路.但是庞大的源码往往让我们不知道从何处开始下手.在很长的时间里我也被 ...
- 从零实现一个简易jQuery框架之一—jQuery框架概述
我们知道,不管学习任何一门框架,了解其设计的理念.目的.总体的结构及核心特性对我们使用和后续的深入理解框架都是有很大的帮助的.因此在这里先梳理一下本人对jQuery框架的一些理解. 设计目的(为什么要 ...
- 第二章 jQuery框架使用准备
window常用属性: History:有关客户访问过的URL的信息 Location: 有关当前url的信息 常用方法: Confirm()将弹出一个确认对话框 open()在页面上弹出一个新的浏览 ...
- 深度理解Jquery 中 offset() 方法
参考原文:深度理解Jquery 中 offset() 方法
随机推荐
- 虚拟机VirtualBox及轻量级的CentOS
1,先下载虚拟机VirtualBox和centos(下边有链接),将VirtualBox安装在本机 2,管理 --> 导入虚拟电脑 --> 选择本地centos文件 3,点击下一步 - ...
- 013PHP基础知识——流程控制(一)
<?php /** * 13 流程控制(一) * if语句: if(表达式){ 表达式 }elseif(表达式){ 代码段 } * if语句中,一个条件成立,其他分支不执行. * if中的表达式 ...
- Java 进阶6 异常处理的陷阱
Java 进阶6 异常处理的陷阱 20131113 异常处理机制是 Java语言的特色之一,尤其是 Java的Checked 异常,更是体现了 Java语言的严谨性:没有完善的错误的代码根本就不会被执 ...
- 记录一个bootstrap因js加载顺序导致的问题(tstrap-table-mobile.min.js:7 Uncaught TypeError: Cannot read property 'defaults' of undefined)
问题描述: 网上找了会没看到答案,然后看了下源码,发现也没有问题,想到js加载的顺序,改了下,发现问题没了. 正确的顺序: 我之前把 <script src="/js/plugins/ ...
- python金融分析项目
1.进入ipython: C:\Users\Administrator>ipython Python (v3. , ::) [MSC v. bit (AM D64)] Type 'copyrig ...
- 【转】netlink socket编程实例
[转]netlink socket编程实例 转自:http://blog.chinaunix.net/uid-14753126-id-2983915.html 关于Netlink IPC方式的介绍,请 ...
- qml 音乐播放器的进度条
进度条采用qml的Slider组件 样式什么的,网上很多.我就不列举了.接下来主要说明,进度条是怎样按秒移动的. Slider { id: control value: 0 stepSize: ...
- c# 加密工具类
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Sec ...
- Android 你可能忽略的提高敲代码效率的方式
Android 你可能忽略的提高敲代码效率的方式
- 11.Linux启动过程详解
目录: 本文转载自:http://blog.csdn.net/miss_acha/article/details/50004717 经过对Linux系统有了一定了解和熟悉后,想对其更深层次的东西做进一 ...