`

JQuery原型

阅读更多

在 JavaScript 中,每个函数对象都有一个默认的属性 prototype,称为函数对象的原型成员,这个属性指向一个对象,称为函数的原型对象,当我们每定义了一个函数的时候,JavaScript 就创建了一个对应的原型对象,也就是说,当我们定义一个函数的时候,实际上得到了两个对象,一个函数对象,一个原型对象。原型对象是一个特殊的对象,函数的 prototype 成员指向它的原型对象。

可以通过函数对象的 prototype 成员取得这个原型对象的引用。

下面定义一个函数对象 Person,然后通过 prototype 来取得它的原型对象。然后在它的原型对象上定义了一个方法。

 
function Person()  
{  
}      
Person.prototype.showPerson = function()  
{  
       alert( "Person Object.");  
}  
    
var alice = new Person();  
alice.showPerson(); 
 这个原型对象上定义的成员将用来共享给所有通过这个函数创建的对象使用。

每个对象也都有一个原型成员 prototype,通过 new 函数创建的对象会通过函数的 prototype 找到函数的原型,然后将自己的原型指向这个对象。对于不是通过函数创建的对象实例和原型对象,它们的原型会被设置为 Object 函数的原型对象。

Object 函数对象是 JavaScript 中定义的顶级函数对象,在 JavaScript 中所有的对象都直接或者间接地使用 Object 对象的原型。当访问对象的属性或者方法的时候,如果对象本身没有这个属性或者方法,那么,JavaScript 会检查对象的 prototype 对象是否拥有这个属性或者方法,如果有,则作为对象的属性或者方法返回,如果没有,那么将通过原型对象的 prototype 继续进行检查,直到原型对象为 Object 函数的原型对象为止。

但是 prototype 是一个特殊的属性,在大多数的浏览器上,例如 IE 浏览器,都不能直接访问对象的 prototype 成员。返回的结果为 undefined。不能赋予对象一个新的原型,只能通过创建它的函数来确定对象的原型。

函数对象的原型有一个特殊的用途,就是通过函数 new 创建出来的对象,会自动将函数对象的原型赋予新创建出的对象的原型。这样,如果为某个函数设置了原型对象,那么,所有通过这个函数创建的对象将拥有同样的原型对象。通过这个方法,可以使这些对象共享相同的属性或者方法,来模拟类型的概念。

 

在 jQuery 中,我们经常使用的 $() 函数就是定义在 window 对象上的 $() 函数。

 
1 jQuery = window.jQuery = window.$ = function( selector, context ) 
2 {
3     // The jQuery object is actually just the init constructor 'enhanced'
4     return new jQuery.fn.init( selector, context );
5 }

这个函数实际上通过 new jQuery.fn.init( selector, context )来完成,也就是通过 init 函数创建了一个对象。

下面重新指定了函数 init 的原型对象。所以 init 函数的原型对象就是 fn 对象。

 
1 // Give the init function the jQuery prototype for later instantiation
2 jQuery.fn.init.prototype = jQuery.fn;

这样所有通过 $ 创建出来的对象都将共享 fn 对象上的成员。因此,jQuery 对象都有了类似 attr 、html 等等方法了。

 

 

 

---------------------------------------------------------分割线----------------------------------------------------------------

 

 

细致的讲:

 

用过javascript的朋友都会明白,在javascript脚本中到处都是函数,函数可以把独立功能封装在一个函数包中。函数也可以实现类,这个类是面线对象编程中最基本的概念。也是最高抽象,定义一个类就相当于制作了一个模型,然后借助这个模型复制很多个实例。 对象:数据+操作这些数据的方法类:具有类似功能的对象的集就是类 所有类都有最基本的功能:继承、派生、重写 Javascript通过所有函数绑定一个prototype属性,这个属性指向一个原型对象,原型对象中可以定义类的属性和方法

  1. var $=jQuery=function(){}   
  2. jQuery.fn=jQuery.prototype={   
  3.     jQuery:"1.3.2",    
  4.     size:function(){   
  5.         return this.length;   
  6.     }   
  7. };  

也许你会采用如下方法调用:

  1. var my$=new $();//实例化   
  2. alert(my$.jQuery);//调用属性,返回1.3.2  

但是,jQuery不是这样调用的:

  1. $().jQuery;  

如果你这样些代码

  1. alert($().jQuery);  

浏览器会显示错误,那jQuery是怎么做的呢 你会发现jQuery没有使用new运算符将jQuery实例化,而是直接调用jQuery函数然后在这个函数后直接调用jQuery的原型方法。怎么实现的呢? 猜测下:我们应给把jQuery看作一个类,同时也要把他视为一个普通的函数,并让这个函数返回jQuery的实例。

  1. var $=jQuery=function(){   
  2.     return new jQuery();//返回jQuery的实例   
  3. }   
  4. jQuery.fn=jQuery.prototype={   
  5.     jQuery:"1.3.2",   
  6.     size:function(){   
  7.         return this.length;   
  8.     }   
  9. };   
  10.   
  11. alert($().jQuery);  

但是浏览器会弹出“ttack overflow at line 8”内存溢出的错误,说明程序出现了死循环引用 回一下,当使用var my$=new $();创建jQuery类的实例时,this关键字就指向my$对象,所以my$对象就获得了jQuery.prototype包含的原型属性和方法,这些方法的关键字就会自动指向my$实例对象。(this关键字总是指向类的实例) 因此我们可以做如下的尝试:在jQuery中使用一个工厂方法来创建一个实例,把这个方法放在原型对象jQuery.prototype中,然后在jQuery函数中返回这个原型方法的调用。

  1. var $=jQuery=function(){   
  2.     return jQuery.fn.init();//返回原型方法init();   
  3. }   
  4. jQuery.fn=jQuery.prototype={   
  5.     init:function(){//在初始化原型方法中返回实例的引用   
  6.      return this;   
  7.     },   
  8.     jQuery:"1.3.2",   
  9.     size:function(){   
  10.         return this.length;   
  11.     }   
  12. };   
  13.   
  14. alert($().jQuery);  

这时就可以成功的显示1.3.2的预期结果了。 继续思考:init()方法返回的是this关键字,该关键字引用的是jQuery类的实例,如果在init函数中继续使用this关键字this。这个this怎么处理呢? 例如:jQuery原型对象包含一个length属性,同时init()从一个普通的函数转变成一个构造器,它可以包含一个length属性和test()方法。运行该实例我们可以看到this引用了init函数作用域所在的对象,此时它访问length属性时,返回0.而this关键字也能够访问上一级对象jQuery.fn对象的作用域,$().jQuery返回“1.3.2”。但是调用$().size()方法时,返回的是0而不是1。

  1. var $=jQuery=function(){   
  2.     return jQuery.fn.init();//返回原型方法init();   
  3. }   
  4. jQuery.fn=jQuery.prototype={   
  5.     init:function(){//在初始化原型方法中返回实例的引用   
  6.         this.length=0;   
  7.         this.test=function(){   
  8.             return this.length;   
  9.         };   
  10.         return this;   
  11.     },   
  12.     jQuery:"1.3.2",   
  13.     length:1,   
  14.     size:function(){   
  15.         return this.length;   
  16.     }   
  17. };   
  18.   
  19. alert($().jQuery);   
  20. alert($().test());   
  21. alert($().size());  

我们可以看到jQuery是通过下面的方法调用init初始化构造函数的:

  1. var $=jQuery=function(){   
  2.     return new jQuery.fn.init();//返回原型方法init();   
  3. }  

这样就可以把init构造器中的this关键字和jQuery.fn中的关键字this分隔开来,避免了相互混淆。但是问题是:无法反问jQuery.fn对象的属性和方法!

  1. var $=jQuery=function(){   
  2.     return jQuery.fn.init();//返回原型方法init();   
  3. }   
  4. jQuery.fn=jQuery.prototype={   
  5.     init:function(){//在初始化原型方法中返回实例的引用   
  6.         this.length=0;   
  7.         this.test=function(){   
  8.             return this.length;   
  9.         };   
  10.         return this;   
  11.     },   
  12.     jQuery:"1.3.2",   
  13.     length:1,   
  14.     size:function(){   
  15.         return this.length;   
  16.     }   
  17. };   
  18.   
  19. alert($().jQuery);//返回undefined   
  20. alert($().test());//返回0   
  21. alert($().size());//抛出异常  

如何做到既能分割初始化构造器函数与jQuery对象的作用域,又能够在返回的实例中访问jQuery原型对象呢?

  1. var $=jQuery=function(){   
  2.     return new jQuery.fn.init();//返回原型方法init();   
  3. }   
  4. jQuery.fn=jQuery.prototype={   
  5.     init:function(){//在初始化原型方法中返回实例的引用   
  6.         this.length=0;   
  7.         this.test=function(){   
  8.             return this.length;   
  9.         };   
  10.         return this;   
  11.     },   
  12.     jQuery:"1.3.2",   
  13.     length:1,   
  14.     size:function(){   
  15.         return this.length;   
  16.     }   
  17. };   
  18. jQuery.fn.init.prototype=jQuery.fn;   
  19. alert($().jQuery);   
  20. alert($().test());   
  21. alert($().size());  

jQuery巧妙的通过原型传递解决了这个问题,它把jQuery.fn传递给jQuery.fn.init.prototype,也就用jQuery的原型对象覆盖init构造器的圆形对象,从而实现跨域访问

 

 

 

 

分享到:
评论

相关推荐

    jQuery原型属性和原型方法详解

    接下来是jQuery原型中定义的几个方法。size方法返回匹配元素集合的元素个数,与length属性相同。而get方法则提供了一个返回指定索引处的元素的途径。例如,$('li').get(0)会返回第一个li元素。 toArray方法将jQuery...

    jQuery学习笔记之jQuery原型属性和方法

    在深入探讨jQuery原型属性和方法之前,需要了解JavaScript中原型继承的基本概念。原型是JavaScript实现继承的一个重要机制,每个对象都有一个原型对象,原型对象也会有自己的原型,直到一个对象的原型为null。这样的...

    JS-Graveyard:未能成功的纯Javascript和jQuery原型

    未能成功的纯Javascript和jQuery原型。 关于 他们有很大的希望,但是浏览器实现方式的差异杀死了他们。 我所面临的大多数问题,当您在各种Web浏览器上运行这些脚本时会立即注意到,这与动画性能(尤其是Internet ...

    Jquery常用方法.txt

    - **描述**:扩展jQuery原型对象,添加自定义的方法。 7. **执行表达式**: - `jQuery(expression,[context])` 或 `$(expression,[context]);` - **描述**:通过提供的表达式获取DOM元素,`context`可选,用于...

    jquery插件精髓(不看后悔)

    #### 扩展jQuery和jQuery原型 `jQuery.extend`不仅可以用于合并对象,还可以用于扩展jQuery自身以及jQuery的原型对象(`$.fn`),从而向jQuery添加自定义方法或属性。 - **扩展jQuery全局对象**: ```javascript ...

    Dreamware的jquery插件

    - 在函数内部,通过`$.fn.extend({})`将新方法添加到jQuery原型链上,使所有jQuery选择器都能访问。 - 插件函数可以接受参数,用于定制行为。 - 最后,确保在使用插件之前引入jQuery库。 2. **Dreamware的jQuery...

    2014-10-04-深入理解jQuery(1)——jQuery对象1

    jQuery原型中包含了许多其他方法,比如`append()`用于向元素添加内容,`addClass()`用于添加CSS类,`on()`用于事件绑定等。这些方法使得开发者能够更高效地操作DOM,无需直接与原生DOM API交互,提高了开发效率和...

    jQuery文章.rar

    通过`.fn.extend()`方法,我们可以向jQuery原型链中添加新的方法。例如,`$.fn.myPlugin = function() {...}`定义了一个名为`myPlugin`的新方法,之后就可以在任何jQuery对象上调用`$(selector).myPlugin()`。在编写...

    jquery 时间选择控件

    - **jQuery插件结构**:典型的jQuery插件模式包括定义一个函数,然后通过$.fn.extend将函数添加到jQuery原型链上,使得所有jQuery对象都能调用该函数。 - **插件参数设置**:时间选择控件通常可以通过参数进行定制,...

    4、jQuery原理,模拟实现jQuery扩展1

    `jQuery.extend()` 和 `$.extend()` 用于合并一个或多个对象到 jQuery 对象或原型链上,增加新的功能。 4. `$(selector)` 之后,返回的是 jQuery 对象,这个对象封装了 DOM 元素的集合,提供了丰富的 API 来操作...

    jQuery_的原型关系图

    jQuery的原型关系图是理解其内部工作原理的关键。在这个图中,我们可以看到对象之间的继承关系,以及jQuery如何扩展和利用JavaScript的原型链机制。 首先,让我们讨论JavaScript的原型(Prototype)概念。在...

    jQuery插件开发学习

    3. **扩展jQuery对象**:使用`$.fn.extend`方法将插件函数添加到jQuery原型链上,这样我们就可以像使用jQuery内置方法一样调用自定义插件。 4. **设置默认选项**:定义一个对象来存储插件的默认配置,这样用户可以...

    JQuery中文帮助文档

    - **开发插件**: 开发者可以根据需要编写自己的jQuery插件,通过`.fn.extend()`方法将新功能添加到jQuery原型链上。 7. **性能优化** - **DOM操作优化**: 避免频繁操作DOM,可以使用文档片段(`$("<div>").append...

    页面原型JQUERY UI

    页面原型JQUERY UI 可直接替换UI CSS

    jQuery插件

    2. **扩展jQuery原型链**: ```javascript $.fn.pluginName = function(options) { // 主函数 }; ``` `$.fn` 是 jQuery.prototype 的别名,扩展它意味着可以将新的方法应用到所有jQuery对象上。 3. **初始化...

    jQuery源代码-1.11.3版(完整有注释)

    8. **$.extend()和$.fn.extend()**:`$.extend()`用于合并对象,`$.fn.extend()`则用于扩展jQuery原型,使得新方法能够被所有jQuery对象使用。 9. **$.ready()**:这个方法用于在文档加载完成后执行函数,确保DOM已...

    HTML5-jQuery插件开发的流程.pdf

    在这个例子中,`#myElement` 是选择的DOM元素,`myPlugin` 是我们之前添加到jQuery原型上的方法,`{ ... }` 是可选的用户设置。 综上所述,HTML5和jQuery插件开发的核心是将业务逻辑封装到自定义对象中,然后将这个...

    Head First Jquery 中文版 .pdf

    - 创建一个jQuery插件通常涉及定义一个函数,并将该函数挂载到jQuery原型对象上。 - 插件可以接受配置参数,以便于定制化使用。 ### jQuery在Web开发中的应用 12. **提高用户体验**:利用jQuery可以轻松实现表单...

Global site tag (gtag.js) - Google Analytics