这是本人结合资料视频总结出来的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框架-框架结构的更多相关文章

  1. 小谈Jquery框架

    现在Jquery框架对于开发人员基本上是无人不知,无人不晓了,用起来十分的方便,特别是选择器十分强大,提高了我们的开发速度.但是好多人也只是停留在了会用的基础上,我个人觉得会用一个框架不算什么,只能说 ...

  2. Jquery框架

    现在Jquery框架对于开发人员基本上是无人不知,无人不晓了,用起来十分的方便,特别是选择器十分强大,提高了我们的开发速度.但是好多人也只是停留在了会用的基础上,我个人觉得会用一个框架不算什么,只能说 ...

  3. jQuery源码逐行分析学习01(jQuery的框架结构简化)

    最近在学习jQuery源码,在此,特别做一个分享,把所涉及的内容都记录下来,其中有不妥之处还望大家指出,我会及时改正.望各位大神不吝赐教!同时,这也是我的第一篇前端技术博客,对博客编写还不是很熟悉,美 ...

  4. jQuery框架-2.jQuery操作DOM节点与jQuery.ajax方法

    一.jQuery操作DOM 内部插入操作: append(content|fn):向每个匹配的元素内部追加内容. prepend(content):向每个匹配的元素内部前置内容. 外部插入操作: af ...

  5. jQuery系列 第二章 jQuery框架使用准备

    第二章 jQuery框架使用准备 2.1 jQuery框架和JavaScript加载模式对比 jQuery框架的加载模式 <script> window.onload = function ...

  6. 从零实现一个简易的jQuery框架之二—核心思路详解

    如何读源码 jQuery整体框架甚是复杂,也不易读懂.但是若想要在前端的路上走得更远.更好,研究分析前端的框架无疑是进阶路上必经之路.但是庞大的源码往往让我们不知道从何处开始下手.在很长的时间里我也被 ...

  7. 从零实现一个简易jQuery框架之一—jQuery框架概述

    我们知道,不管学习任何一门框架,了解其设计的理念.目的.总体的结构及核心特性对我们使用和后续的深入理解框架都是有很大的帮助的.因此在这里先梳理一下本人对jQuery框架的一些理解. 设计目的(为什么要 ...

  8. 第二章 jQuery框架使用准备

    window常用属性: History:有关客户访问过的URL的信息 Location: 有关当前url的信息 常用方法: Confirm()将弹出一个确认对话框 open()在页面上弹出一个新的浏览 ...

  9. 深度理解Jquery 中 offset() 方法

    参考原文:深度理解Jquery 中 offset() 方法

随机推荐

  1. ( 转)Sqlserver中tinyint, smallint, int, bigint的区别 及 10进制转换16进制的方法

    一.类型比较 bigint:从-2^63(-9223372036854775808)到2^63-1(9223372036854775807)的整型数据,存储大小为 8 个字节.一个字节就是8位,那么b ...

  2. webapi在IIS发布后报Http 403.14 error

    服务器是Windows Server 2008 R2 Enterprise IIS6.1     解决方法,修改web.config文件   1.在<system.webServer>配置 ...

  3. CF991C

    题解: 很显然不会有那么多种肯能 所以都列出来即可 代码: #include<bits/stdc++.h> using namespace std; int main() { ]; sca ...

  4. Node.js 全栈开发(一)——Web 开发技术演化

    这些年一直不断接触学习 Node 技术栈,个人的技术开发学习兴趣也越来越倾向 node 流.也许是由于英语的关系,也许是因为墙增加了学习国外一手资料的难度,加上现在流行的 web 开发技术并不太容易上 ...

  5. Linux服务器上安装tomcat

    安装软件 : apache-tomcat-9.0.0.M1.tar.gz(下载地址http://tomcat.apache.org/) 步骤一 Tomcat是其中一个开源的且免费的java Web服务 ...

  6. 各排序算法的Java实现及简单分析

    一,直接插入排序 //直接插入排序的算法时间复杂度分析: //如果输入为正序,则每次比较一次就可以找到元素最终位置,复杂度为O(n) //如果输入为反序,则每次要比较i个元素,复杂度为O(n2) // ...

  7. java中遍历类中的属性、调用getter&setter方法

    public static void testReflect(Object model) throws NoSuchMethodException, IllegalAccessException, I ...

  8. 使用kibana来进行ElasticSearch的信息查询检索

    大家经常会听到使用ELK搭建日志管理平台.完成日志聚合检索的功能,那么这个平台到底是个什么概念,怎么搭建,怎么使用呢? ELK包括ElasticSearch(数据存储.快速查询).logstash(日 ...

  9. RxJava 1.x 笔记:组合型操作符

    最近去检查眼睛,发现度数又涨了,唉,各位猿多注意保护自己的眼睛吧! 前面学了 RxJava 的三种关键操作符: 创建型操作符 过滤型操作符 变换型操作符 读完本文你将了解第四种(组合型操作符): 组合 ...

  10. xcode6 添加.pch文件

    1, 新建文件 (command+N)ios-选择other组,再次选择PCH File,输入文件名保存. eg: 创建的工程为Demo; 创建文件名为DemoPrefixHeader.pch 2,到 ...