浅析jQuery核心架构中应用Closure的设计模式
2011-11-03 09:57
211 查看
用了很久jQuery,到最近,等到自己想写一个链式库时才对它的内部架构学习了一下。下面就对jQuery框架设计模式的一些感想写一下:
首先是jQuery将自己所有的代码封装在一个闭包内;用闭包防止命名空间的变量污染,继续在本身闭包中初始化了一个名为jQuery的自动运行闭包函数;
形如:
Js代码
(function(window, undefined){
var jQuery = (function(){})();
})();
想如此的匿名函数赋值语句,一般就会返回一个内嵌函数如下:
Js代码
var jQuery = (function(){
var jQuery = function(){
//TODO
}
return (window.$ = window.jQuery = jQuery);
});
而这个内嵌函数在return时做了外部对象(window) 的引用以及外部的调用的,所以根js的词法作用域规则,在上层函数运行后它仍将保存其作用域(相当于包含其函数内部调用的外层函数私有变量不会被垃圾回收 机制回收掉),这里的jQuery函数在作为window这个全局对象中的引用后便保存了它在上层jQuery函数中调用的所用变量作用域。而这些变量也 是jQ自身的属性。
然后会在这个内嵌函数中写入如此的语句:
Js代码
var jQuery = (function(){
var jQuery = function(){
return new jQuery.fn.init(selector, context);
}
return (window.$ = window.jQuery = jQuery);
});
这里的jQ函数返回一个新new出来的对象,相当于类的构造函数实际是一个对象工厂函数,而这个对象则是自己prototype里的一个方法的对象,这边的fn属性既是jQuery的原型而已,而下面的init则是其初始化函数
我们平时用的fn的插件实际是jQ的原型(注意:这边返回的必须是构造函数而不是new好的对象)
Js代码
var jQuery = (function(){
var jQuery = function(){
return new jQuery.fn.init(selector, context);
}
jQuery.fn = jQuery.prototype = {
init: function(){}
};
return (window.$ = window.jQuery = jQuery);
});
恩,上面的便是返回了一个init为构造函数的一个对象,相当于说是我们平时用的jQuery对象实质上是jQ对象自己原型中的一个构造函数对象,这个对象是init对象,并不是jQuery对象本身,所以它的原型是空的,并不包含jQ的原型,所以下面这句话异常重要。
将init的原型指向fn,而fn是指向jQ的原型,相当于init的原型是指向jQ的原型的
jQuery.fn.init.prototype = jQuery.fn;
之后代码变成了这样:
Js代码
var jQuery = (function(){
var jQuery = function(){
return new jQuery.fn.init(selector, context);
}
jQuery.fn = jQuery.prototype = {
init: function(){}
};
jQuery.fn.init.prototype = jQuery.fn;
return (window.$ = window.jQuery = jQuery);
});
再然后便可以往jQ类中加入静态对象,放在内核内的这里的对象或方法往往是要调用对象内私有属性的,下面是对jQ命名空间的工厂函数:
jQuery.extend = jQuery.fn.extend = function(){}
实际上也是jQ原型中定义的一个扩展函数
至此jQ的内核已经结束。接下来时外层闭包中的jQuery对象,这个对象首先持有了内层返回的jQ对象,而这个对象同样其实是一个函数,或者更确切的说是一个类构造函数,然后就可以在外闭包中放一些无需依赖jQ类私有变量的库函数。再对这个类附上库函数。
Js代码
(function(window, undefined){
<span style="white-space: pre;"> </span>//内核
var jQuery = (function(){})();
//非依赖私有变量的类方法
(function(){
//可以直接调用jQuery外层应用类对其进行扩展
jQuery.support = {};
jQuery.extend({/*TODO*/}
})();
})();
而我们平时用的$(//TODO)或是jQuery(//TODO)则是在用jQ中的init方法new 出一个jQ的对象(更确切说是init对象)
下面是类似于jQ的全局对象构造机制的自己实现的一个函数
Js代码
(function(){
function _$(ele){
this.eles = [];
for(var i = 0, i < eles.length ;++i){
var ele = ele[i];
if(typeof ele == 'string'){
ele = document.getElementById(element);
}
this.eles.push(ele);
}
}
window.$ = function(){
return new _$(arguments);
}
})();
总结:对于jQ的这种closure的封装机制的确对项目的空间隔离有很大的借鉴意义,双层闭包和内调用首先可以防止命名空间污染,其次逻辑结构也非常清晰,对于内层私有变量的保护和外层库的扩展这种设计的模式在以后的开发中也有很大的借鉴意义。
首先是jQuery将自己所有的代码封装在一个闭包内;用闭包防止命名空间的变量污染,继续在本身闭包中初始化了一个名为jQuery的自动运行闭包函数;
形如:
Js代码
(function(window, undefined){
var jQuery = (function(){})();
})();
想如此的匿名函数赋值语句,一般就会返回一个内嵌函数如下:
Js代码
var jQuery = (function(){
var jQuery = function(){
//TODO
}
return (window.$ = window.jQuery = jQuery);
});
而这个内嵌函数在return时做了外部对象(window) 的引用以及外部的调用的,所以根js的词法作用域规则,在上层函数运行后它仍将保存其作用域(相当于包含其函数内部调用的外层函数私有变量不会被垃圾回收 机制回收掉),这里的jQuery函数在作为window这个全局对象中的引用后便保存了它在上层jQuery函数中调用的所用变量作用域。而这些变量也 是jQ自身的属性。
然后会在这个内嵌函数中写入如此的语句:
Js代码
var jQuery = (function(){
var jQuery = function(){
return new jQuery.fn.init(selector, context);
}
return (window.$ = window.jQuery = jQuery);
});
这里的jQ函数返回一个新new出来的对象,相当于类的构造函数实际是一个对象工厂函数,而这个对象则是自己prototype里的一个方法的对象,这边的fn属性既是jQuery的原型而已,而下面的init则是其初始化函数
我们平时用的fn的插件实际是jQ的原型(注意:这边返回的必须是构造函数而不是new好的对象)
Js代码
var jQuery = (function(){
var jQuery = function(){
return new jQuery.fn.init(selector, context);
}
jQuery.fn = jQuery.prototype = {
init: function(){}
};
return (window.$ = window.jQuery = jQuery);
});
恩,上面的便是返回了一个init为构造函数的一个对象,相当于说是我们平时用的jQuery对象实质上是jQ对象自己原型中的一个构造函数对象,这个对象是init对象,并不是jQuery对象本身,所以它的原型是空的,并不包含jQ的原型,所以下面这句话异常重要。
将init的原型指向fn,而fn是指向jQ的原型,相当于init的原型是指向jQ的原型的
jQuery.fn.init.prototype = jQuery.fn;
之后代码变成了这样:
Js代码
var jQuery = (function(){
var jQuery = function(){
return new jQuery.fn.init(selector, context);
}
jQuery.fn = jQuery.prototype = {
init: function(){}
};
jQuery.fn.init.prototype = jQuery.fn;
return (window.$ = window.jQuery = jQuery);
});
再然后便可以往jQ类中加入静态对象,放在内核内的这里的对象或方法往往是要调用对象内私有属性的,下面是对jQ命名空间的工厂函数:
jQuery.extend = jQuery.fn.extend = function(){}
实际上也是jQ原型中定义的一个扩展函数
至此jQ的内核已经结束。接下来时外层闭包中的jQuery对象,这个对象首先持有了内层返回的jQ对象,而这个对象同样其实是一个函数,或者更确切的说是一个类构造函数,然后就可以在外闭包中放一些无需依赖jQ类私有变量的库函数。再对这个类附上库函数。
Js代码
(function(window, undefined){
<span style="white-space: pre;"> </span>//内核
var jQuery = (function(){})();
//非依赖私有变量的类方法
(function(){
//可以直接调用jQuery外层应用类对其进行扩展
jQuery.support = {};
jQuery.extend({/*TODO*/}
})();
})();
而我们平时用的$(//TODO)或是jQuery(//TODO)则是在用jQ中的init方法new 出一个jQ的对象(更确切说是init对象)
下面是类似于jQ的全局对象构造机制的自己实现的一个函数
Js代码
(function(){
function _$(ele){
this.eles = [];
for(var i = 0, i < eles.length ;++i){
var ele = ele[i];
if(typeof ele == 'string'){
ele = document.getElementById(element);
}
this.eles.push(ele);
}
}
window.$ = function(){
return new _$(arguments);
}
})();
总结:对于jQ的这种closure的封装机制的确对项目的空间隔离有很大的借鉴意义,双层闭包和内调用首先可以防止命名空间污染,其次逻辑结构也非常清晰,对于内层私有变量的保护和外层库的扩展这种设计的模式在以后的开发中也有很大的借鉴意义。
相关文章推荐
- 浅析jQuery核心架构中应用Closure(闭包)的设计模式
- 企业应用架构设计--关系结构模式(第12章)
- 重新认识分层架构(现代企业级应用分层架构核心设计要素)
- PHP中的设计模式及其实际应用浅析
- (札记)Java应用架构设计-模块化模式与OSGi
- .NET应用架构设计―重新认识分层架构(现代企业级应用分层架构核心设计要素)
- 谈一谈jQuery核心架构设计
- Java应用架构设计:模块化模式与OSGi
- Cloud Native时代SaaS类Web应用的后端数据库架构设计:核心概念的简化:主键设计
- 消息订阅、派送设计模式在“平台-插件”式软件架构设计中的应用
- .NET应用架构设计—再次了解分层架构(现代企业应用分层架构核心设计元素)
- 基于MVP设计模式的Android应用架构设计
- 重构Minot's应用——ios网络通信中的设计模式与架构设计
- Unity应用架构设计(1)—— MVVM 模式的设计和实施(Part 2)
- .NET应用架构设计—重新认识分层架构(现代企业级应用分层架构核心设计要素)
- java应用架构设计(模块化模式与OSGI)
- 关于软件架构、设计模式和应用框架的一点看法
- Cloud Design Patterns: Prescriptive Architecture Guidance for Cloud Applications 云设计模式:云应用的规范架构指导
- <<.NET B/S 架构实践>> 几种概念区别 - 算法、设计模式、企业应用架构模式、架构模式
- 浅析jQuery的基础设计模式