加入收藏 | 设为首页 | 会员中心 | 我要投稿 温州站长网 (https://www.0577zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

jQuery中的编程范式详解

发布时间:2016-11-23 14:48:47 所属栏目:Linux 来源:站长网
导读:本文详细分析了jQuery中的编程范式。分享给大家供大家参考。具体如下: 浏览器前端编程的面貌自2005年以来已经发生了深刻的变化,这并不简单的意味着出现了大量功能丰富的基础库,使得我们可以更加方便的编写业务代码,更重要的是我们看待前端技术的观念发

如果D类从A,B两个基类继承, 而A和B类中都实现了同一个函数f, 那么D类中的f到底是A中的f还是B中的f, 抑或是A中的f+B中的f呢#63; 这一困境的出现实际上源于D的基类A和B是并列关系, 它们满足交换律和结合律, 毕竟,在概念层面上我们可能难以认可两个任意概念之间会出现从属关系. 但如果我们放松一些概念层面的要求, 更多的从操作层面考虑一下代码重用问题, 可以简单的认为B在A的基础上进行操作, 那么就可以得到一个线性化的结果. 也就是说, 放弃A和B之间的交换律只保留结合律, extends A, B 与 extends B,A 会是两个不同的结果, 不再存在诠释上的二义性. scala语言中的所谓trait(特性)机制实际上采用的就是这一策略.

面向对象技术发明很久之后, 出现了所谓的面向方面编程(AOP), 它与OOP不同, 是代码结构空间中的定位与修改技术. AOP的眼中只有类与方法, 不知道什么叫做意义. AOP也提供了一种类似多重继承的代码重用手段, 那就是mixin. 对象被看作是可以被打开,然后任意修改的Map, 一组成员变量与方法就被直接注射到对象体内, 直接改变了它的行为.
nbsp; prototype.js库引入了extend函数,
复制代码 代码如下:Object.extend = function(destination, source) {
nbsp;nbsp;nbsp; for (var property in source) {
nbsp;nbsp;nbsp;nbsp;nbsp; destination[property] = source[property];
nbsp;nbsp;nbsp; }
nbsp;nbsp;nbsp; return destination;
nbsp; }

就是Map之间的一个覆盖运算, 但很管用, 在jQuery库中也得到了延用. 这个操作类似于mixin, 在jQuery中是代码重用的主要技术手段---没有继承也没什么大不了的.

11. 名称映射: 一切都是数据

代码好不好, 循环判断必须少. 循环和判断语句是程序的基本组成部分, 但是优良的代码库中却往往找不到它们的踪影, 因为这些语句的交织会模糊系统的逻辑主线, 使我们的思想迷失在疲于奔命的代码追踪中. jQuery本身通过each, extend等函数已经极大减少了对循环语句的需求, 对于判断语句, 则主要是通过映射表来处理. 例如, jQuery的val()函数需要针对不同标签进行不同的处理, 因此定义一个以tagName为key的函数映射表
复制代码 代码如下:valHooks: { option: {get:function(){}}}
这样在程序中就不需要到处写
复制代码 代码如下:if(elm.tagName == 'OPTION'){
nbsp;nbsp;nbsp;nbsp; return ...;
nbsp;nbsp; }else if(elm.tagName == 'TEXTAREA'){
nbsp;nbsp;nbsp;nbsp; return ...;
nbsp;nbsp; }
可以统一处理
复制代码 代码如下:(valHooks[elm.tagName.toLowerCase()] || defaultHandler).get(elm);
nbsp;nbsp;
映射表将函数作为普通数据来管理, 在动态语言中有着广泛的应用. 特别是, 对象本身就是函数和变量的容器, 可以被看作是映射表. jQuery中大量使用的一个技巧就是利用名称映射来动态生成代码, 形成一种类似模板的机制. 例如为了实现myWidth和myHeight两个非常类似的函数, 我们不需要
复制代码 代码如下:jQuery.fn.myWidth = function(){
nbsp;nbsp;nbsp;nbsp;nbsp; return parseInt(this.style.width,10) + 10;
nbsp;nbsp;nbsp; }
nbsp;nbsp;nbsp;
nbsp;nbsp;nbsp; jQuery.fn.myHeight = function(){
nbsp;nbsp;nbsp;nbsp;nbsp; return parseInt(this.style.height,10) + 10;
nbsp;nbsp;nbsp; }
而可以选择动态生成
复制代码 代码如下:jQuery.each(['Width','Height'],function(name){
nbsp;nbsp;nbsp;nbsp;nbsp; jQuery.fn['my'+name] = function(){
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; return parseInt(this.style[name.toLowerCase()],10) + 10;
nbsp;nbsp;nbsp;nbsp;nbsp; }
nbsp;nbsp;nbsp; });
nbsp;
12. 插件机制:其实我很简单nbsp;nbsp;nbsp;

jQuery所谓的插件其实就是$.fn上增加的函数, 那这个fn是什么东西#63;
复制代码 代码如下:(function(window,undefined){
nbsp;nbsp;nbsp; // 内部又有一个包装
nbsp;nbsp;nbsp; var jQuery = (function() {
nbsp;nbsp;nbsp;nbsp;nbsp; var jQuery = function( selector, context ) {
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; return new jQuery.fn.init( selector, context, rootjQuery );
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; }
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; ....
nbsp;nbsp;nbsp;nbsp;nbsp; // fn实际就是prototype的简写
nbsp;nbsp;nbsp;nbsp;nbsp; jQuery.fn = jQuery.prototype = {
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; constructor: jQuery,
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; init: function( selector, context, rootjQuery ) {...nbsp; }
nbsp;nbsp;nbsp;nbsp;nbsp; }
nbsp;nbsp;nbsp;
nbsp;nbsp;nbsp;nbsp;nbsp; // 调用jQuery()就是相当于new init(), 而init的prototype就是jQuery的prototype
nbsp;nbsp;nbsp;nbsp;nbsp; jQuery.fn.init.prototype = jQuery.fn;
nbsp;nbsp;nbsp;
nbsp;nbsp;nbsp;nbsp;nbsp; // 这里返回的jQuery对象只具备最基本的功能, 下面就是一系列的extend
nbsp;nbsp;nbsp;nbsp;nbsp; return jQuery;
nbsp;nbsp;nbsp; })();nbsp;
nbsp;nbsp;nbsp; ...
nbsp;nbsp;nbsp;nbsp; // 将jQuery暴露为全局对象
nbsp;nbsp;nbsp; window.jQuery = window.$ = jQuery;
})(window);

显然, $.fn其实就是jQuery.prototype的简写.
nbsp;
无状态的插件仅仅就是一个函数, 非常简单.
复制代码 代码如下:// 定义插件
nbsp; (function($){
nbsp;nbsp;nbsp;nbsp;nbsp; $.fn.hoverClass = function(c) {
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; return this.hover(
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; function() { $(this).toggleClass(c); }
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; );
nbsp;nbsp;nbsp;nbsp;nbsp; };
nbsp; })(jQuery);
nbsp;
nbsp; // 使用插件
nbsp; $('li').hoverClass('hover');
nbsp;
对于比较复杂的插件开发, jQuery UI提供了一个widget工厂机制,
复制代码 代码如下:$.widget("ui.dialog", {
nbsp;nbsp; options: {
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; autoOpen: true,...
nbsp;nbsp;nbsp;nbsp; },
nbsp;nbsp;nbsp;nbsp; _create: function(){ ... },
nbsp;nbsp;nbsp;nbsp; _init: function() {
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; if ( this.options.autoOpen ) {
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; this.open();
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; }
nbsp;nbsp;nbsp;nbsp; },
nbsp;nbsp;nbsp;nbsp; _setOption: function(key, value){ ... }
nbsp;nbsp;nbsp;nbsp; destroy: function(){ ... }
nbsp;});
nbsp;
调用 $('#dlg').dialog(options)时, 实际执行的代码基本如下所示:
复制代码 代码如下:this.each(function() {
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; var instance = $.data( this, "dialog" );
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; if ( instance ) {
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; instance.option( options || {} )._init();
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; } else {
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; $.data( this, "dialog", new $.ui.dialog( options, this ) );
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; }
nbsp;nbsp;nbsp; }
可以看出, 第一次调用$('#dlg').dialog()函数时会创建窗口对象实例,并保存在data中, 此时会调用_create()和_init()函数, 而如果不是第一次调用, 则是在已经存在的对象实例上调用_init()方法. 多次调用$('#dlg').dialog()并不会创建多个实例.

13. browser sniffer vs. feature detection

(编辑:温州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读