读jQuery之一(对象的组成)

对于jQuery的写法甚是困惑,尤其在使用Prototype的$后,一度不能理解jQuery的$。对于现在前端同学来说,可能第一个接触的就是jQuery了,他们会觉得很习惯,很自然。

至今电脑里还存放着当时的API文档,发个图感叹下

在这段时间内,我的入门老师是墨墨,其实至今他仍然是我敬仰的同事之一。他的编程造诣很高,相信早已突破了编程语言的限制。在大家都在使用Prototype.js的时候,在jQuery尚未在国内流行的时候,他就已经把jQuery引入到项目中了。

言归正传吧,目前的jQuery版本已经到了1.6.1。从当时的2000行左右膨胀到了9000行。相信不久就会突破1w行。对于一些简单网页来说引入一个jQuery已经不再那么轻量了。这里的研读的是1.6.1这个版本,我会边读边写,最后会写出一个1000行左右的“迷你jQuery”。

以下是jQuery 1.6.1 代码片段


代码如下:

var jQuery = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
return new jQuery.fn.init( selector, context, rootjQuery );
},
...
class2type = {};

jQuery.fn = jQuery.prototype = {
constructor: jQuery,
init: function(selector, context, rootjQuery){
}
}

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

初看上去像是在用 原型方式 在写一个类jQuery(别名$),但实际我们使用时是函数调用$("#id"),却不是new $("#id")。
标识符 jQuery是一个function,其内new了一个function init的实例,然后返回。至此我们知道其真正的构造器是jQuery.fn.init。jQuery写的实在诡异,它把init又挂在了jQuery的prototype上,阅读起来有些绕人。

jQuery.fn.init.prototype = jQuery.fn; 是关键的一句。该句把function jQuery的原型赋值给了function init的原型。当调用$("#id")时返回的对象组成包括两个部分。
1,由function init中this带的(如this.context);
2,由function jQuery的prototype带的(如this.size/this.toArray);

模仿jQuery写一个


代码如下:

// zchain-0.1.js
function $(selector){
return new $.prototype.init(selector);
}
$.prototype={
init:function(selector){
if(selector === undefined){
this.length = 0;
return this;
}
if(selector.nodeType==1){
this[0] = selector;
}else{
this[0]=document.getElementById(selector);
}
this.length=1;
},
css:function(name,value){
this[0].style[name] = value;
return this;//链式调用
},
hide:function(){
var self=this;
setTimeout(function(){
self[0].style.display="none";
},3000);
return this;//链式调用
}
}
$.prototype.init.prototype=$.prototype;

简单起见,这里选择器只传html element或元素id(后续会增强,但不实现全部css selector),this上挂了length属性,赋值为1。
当我们调用时


代码如下:

var obj = $();
console.dir(obj);

$()实际没有什么意义,只是为了测试调用后obj的组成。firebug控制台输出如下:
length:0;
init:function
attr:function
hide:function

即obj对象是由function init中this及function $.prototype组成的。
再看下$.prototype上的方法,我只添加了css和hide方法,这两个方法的实现也是极其简陋的。


代码如下:

<script src="http://files.cnblogs.com/snandy/zchain-0.1.js"></script>
<div id='content'>3 seconds later I will hide.</div>
<script type="text/javascript">
$("content").css("color","red").hide();
</script>

先调用css设置了字体颜色为红色,3秒后隐藏了。
总结下:
jQuery对象指的是jQuery.prototype.init的实例,简单的说就是new jQuery.prototype.init。这里jQuery.prototype.init的类型是function,可以看成是一个类。

jQuery对象由以下部分组成:
1,挂在jQuery.prototype.init中的this上的属性或方法。
2,挂在jQuery.prototype.init.prototype上的属性或方法。
3,因为把jQuery.prototype赋值给了jQuery.prototype.init.prototype,所以挂在jQuery.prototype上的属性和方法也是jQuery对象的一部分。
4,通过jQuery.fn.extend({...})方式扩展的属性或方法(后续提到)。
/201106/yuanma/zchain.rar

(0)

相关推荐

  • 读jQuery之六 缓存数据功能介绍

    很多同学在项目中都喜欢将数据存储在HTMLElement属性上,如 复制代码 代码如下: <div data="some data">Test</div> <script> div.getAttribute('data'); // some data </script> 给页面中div添加了自定义属性"data"及值"some data".后续JS代码中使用getAttribute获取. jQuer

  • 读jQuery之二(两种扩展)

    如下 复制代码 代码如下: jQuery.extend = jQuery.fn.extend = function() { ... }; 我们可以用$.extend去扩展自定义的对象,如 复制代码 代码如下: var myself = {name:jack}; $.extend(myself, {setName: function(n){this.name=n;} }); myself.setName("tom"); 通过$.extend为对象myself添加了setName方法.但这

  • 读jQuery之七 判断点击了鼠标哪个键的代码

    jQuery丢弃了标准的 button 属性采用 which,这有点让人费解. which 是Firefox引入的,IE不支持.which的本意是获取键盘的键值(keyCode). jQuery中的which即可以是键盘的键值,也可以是鼠标的键值.即当判断用户按下键盘的哪个键时可以使用which,当判断用户按下鼠标的哪个键时也可以用which.它一举两用了.源码 复制代码 代码如下: // Add which for key events if ( event.which == null &&am

  • 读jQuery之四(优雅的迭代)

    jQuery的操作往往是分两步 1,获取元素集合(选择器) 2,操作元素集合 而第二步操作元素集合的主要方法就是jQuery.each.查看源码,我们发现jQuery.each及this.each分别调用了27次和31次.可见它是多么的重要. 这篇将分析下jQuery.each及this.each方法.看看他们如何与jQuery.extend一起扩展jQuery库.最后我会给zChain.js加上each方法. 部分源码如下 复制代码 代码如下: jQuery.fn = jQuery.proto

  • 读jQuery之十一 添加事件核心方法

    这篇看看其源码,这个add定义如下(省略大部分) 复制代码 代码如下: add: function( elem, types, handler, data ) { if ( elem.nodeType === 3 || elem.nodeType === 8 ) { return; } ... } 定义了四个参数elem.types.handler和data分别为HTMLElement.事件类型(如click).事件响应函数.数据.此外,types 可以以空格分开传多种事件("mouseover

  • 读jQuery之三(构建选择器)

    为了叙述每一篇的重点,其示例代码都是最精简的,比如选择器只能传HTMLElement和id. 这篇我们增强下选择器,依据2/8原则,这里仅实现最常用的几种. 1, 通过id获取,该元素是唯一的$('#id') 2, 通过className获取$('.cls') 获取文档中所有className为cls的元素$('.cls', el)$('.cls', '#id')$('span.cls') 获取文档中所有className为cls的span元素$('span.cls', el) 获取指定元素中c

  • 读jQuery之八 包装事件对象

    比如,停止事件冒泡IE用 cancelBubble ,标准浏览器则用 stopPropagation . 获取事件源对象,IE用 srcElement ,标准浏览器则用 target 诸如此类. jQuery 对原生事件对象的修复和包装主要使用 jQuery.Event 类和 jQuery.event.fix 方法. 复制代码 代码如下: jQuery.Event = function( src ) { // Allow instantiation without the 'new' keywo

  • 读jQuery之十二 删除事件核心方法

    .remove 所作的事情与上一篇提到的.add 刚好相反.且与.add中的处理代码一一对应,即  .add 中有多少种添加事件的方式.remove就有对应的删除方式. .remove 定义了四个参数 elem, types, handler, pos .从字面上看四个参数的意义很明了 elem 为HTMLElement types 为String类型,事件名称如'click'或'mouseover mouseout' handler 为Function类型,事件回调函数 pos 为Number

  • 读jQuery之五(取DOM元素)

    jQuery的$调用后想要获取DOM元素可以使用get方法,如下 复制代码 代码如下: // 方式1 $('div').get(1); // 获取页面中第二个div 当然,也可以使用数组索引方式获取 复制代码 代码如下: // 方式2 $('div')[1]; // 获取页面中第二个div 上面两种方式都可以获取某一个特定的DOM元素,而获取DOM元素集合却要使用toArray方法 复制代码 代码如下: $('div').toArray(); // 返回页面中所有的div,依次放入数组中 看看g

  • 读jQuery之九 一些瑕疵说明

    1,bind 方法,最后一个参数fn是多余的 复制代码 代码如下: // Handle object literals if ( typeof type === "object" ) { for ( var key in type ) { this[ name ](key, data, type[key], fn); } return this; } 2,注释 复制代码 代码如下: // Add which for click: 1 === left; 2 === middle; 3

  • 读jQuery之十 事件模块概述

    后面会详细分析jQuery.event.add/jQuery.event.remove/jQuery.event.trigger. 虽然事件模块代码很难读,但其提供的API接口还是很清晰的.如下 1 添加事件(bind/one/live/delegate/hover/toggle) bind 基本的添加事件函数. one 添加只执行一次的事件函数. live 事件代理(使用document代理). delegate 事件代理(使用指定元素代理). hover 模拟css的hover. toggl

随机推荐