学习javascript并解读JQuery
很多人都在用javascript,都在用JQuery(这是一个很不错的类库)。然而大多数人的知识面却停留在C# Java的语法上,所以用起js也只是皮毛,想打开JQuery看一看学一学,发现简直是乱码,无从下手,该如何是好?!
这块痛定思痛,就要从这个难啃的骨头下手,相信,如果把这块读懂,那碰到其他一些羞涩的JS代码也就不怕了。
起步:先看一下javascript在常用的页面中做点啥。
想来想去,无非就是,找到个控件,挂个事件,在事件中,取得对象,设置其属性,或样式,来修改其展示。
事件绑定:<inputtype="button"id="aa"value="Hello"onclick="TestFun()"/>
处理事件:function TestFun() { …}
获取对象:var obj = document.getElementById("sp");
设置属性:obj.innerHTML=” <b>Hello</b>”;
改进:再看一下使用JQuery后如何写法:
事件绑定:与上面一样
处理事件:与上面一样
获取对象并设置属性:$("#sp").Html(“<b>Hello</b>”);
再加点:$.style(document.getElementById("sp"),“class”,“MyClass”);
分析:
上面第1句JQuery中,$(“#sp”)为获取对象类创建一个JQuery类,然后立即调用Html函数。
上面第2名JQuery中,$.style(…)可以视为静态函数。
从上面代码看来,的确会使我们编写代码方便得多。当然上面只展示了两个函数,事实上,JQuery中有着大量的处理函数,方便我们对对象进行控件:修改属性、控制显示隐藏、动画显示、修改样式等,还有大量的静态方法供我们使用。
遐想:
看着上面两小段JQuery代码,总结下来,不就是类、函数、静态函数么。
所以很快,我们套用C#写法,来实现之:
publicclass JQuery
{
public JQuery(string objid)
{
obj = document.getElementById(objid);
}
object obj;
publicvoid Html(string content){ …}
publicstaticvoid style(object obj, stirng name,string value){ …}
}
public JQuery $(obj){ returnnew JQuery(obj);}
比较:
现在用c#写的伪代码已经写好,是时候去比较下JQuery源代码了。打开jquery-1.4.2.js文件,发现傻眼了,搜连接个class定义都没有,如何是好。
砍代码:
当我看到大堆的代码,又莫不清里面的逻辑时,我喜欢砍代码,将jquery.js砍到只留下必要的代码,能够让我上面的小示例跑起来为止,把大量先不用的函数去掉,只留下必要的代码。结果如下(这个砍的过程就不详述):
<html>
<head>
<script>
1. (function (window,undefined) {
2. var jQuery = function (obj) {
3. returnnew jQuery.fn.init(obj,null);
4. }
5. jQuery.fn = jQuery.prototype= {
6. init: function (selector,context) {
7. obj=document.getElementById(selector.substring(1));
8. returnthis;
9. },
10. obj:null,
11. };
12. jQuery.fn.init.prototype =jQuery.fn;
13. jQuery.extend =jQuery.fn.extend = function () {
14. for (name in arguments[0]) {
15. this[name] =arguments[0][name];
16. }
17. returnthis;
18. };
19. jQuery.fn.extend({
20. Html: function (value) {
21. obj.innerHTML = value;
22. returnthis;
23. },
24. Hide: function () {
25. obj.style.display = "none";
26. returnthis;
27. }
28. });
29. jQuery.extend({
30. style: function (elem,name, value) {
31. elem.style[name]= value;
32. alert("静态方法调用");
33. }
34. });
35. window.jQuery = window.$ =jQuery;
36. })(window);
</script>
<script>
function TestFun() {
$("#sp").Html("<B>World!</B>");
$.style(document.getElementById("sp"),"class","NewClass");
}
</script>
</head>
<body>
<inputtype="button"id="aa"value="Hello"onclick="TestFun()"/>
<br/>
<spanid="sp"></span>
</body>
</html>
解剖分析:
诈一看,上面这段代码,好像也不是太好理解。不急,慢慢来,一步步边学习javascript特性边来分析这段代码。
如果想跟上节奏,建议先把上面代码粘到一个test.html中,然后跑一下。
函数: 定义一个javascript函数,跟C#差不多,如下: function test(obj){ return"hello"+obj;} 调用函数可以为var ret=test(“World”); 再又有一点,js中的函数可以像变量一样传来传去,比如下面的示例: var aa =test; var ret = aa(””); 上面的示例可以看来,test可以赋给aa,然后再调aa后,同样得到Hello值。如果用C++理解,可以为函数指地,用C#理解,这块可以理解为delegate。
|
好了,来先看大的整个js框架如下,发现:
(function (window,undefined) {...})(window);
这就是一个典型的匿名函数定义然后立即调用,即可以不写函数名,换句这样理解上面代码:
function MyFun(window,undefined){...};
MyFun(window);
定义一个函数MyFun,然后紧跟着立即执行。
匿名函数: Javascript允许有用户可以不定义函数名,比如上面这个test中,只是给这个ret调用,那可以这样写: var ret=(function test(obj){ return"hello"+obj;})(“ World”); 这样写后,这个ret将会得到 “hello world” 这个值。 |
类: Javascript是一个支持面向对象的语言,但与C#,java不同,js所创建的类称之为“伪类”,其定义方法如下: var jQuery = function (){…}
一个方法即可以变成类。那这个类中的函数如何定义呢: 方式一:jQuery.extend = function () {…} 方式二:jQuery[“extend”] = function () {…} 方式三:jQuery.prototype={ extend: function () {…} } 以上几种方法都是定义一个叫“extend”的方法。使用方法,那就跟C#一样,jQuery.extend()。即可调用该方法。
添加函数方法如此,同时js允许动态执行,即可以在运行过程中来添加一个函数,而不象C#先写好后编译。如果这个类不需要这个函数里,可以这样写:delete jQuery.extend。 |
了解这些后,我们就可以看一下上面的代码了,不难发现:
2. var jQuery = function (obj) {
创建了一个jQuery的类
5. jQuery.fn = jQuery.prototype= {
在jQuery下创建一个子类fn 和prototype 结构相同,其下有方法init和obj属性
13. jQuery.extend =jQuery.fn.extend = function () {
这段代码采用了方式一,在jQuery和jQuery.fn类下创建方法extend
插播一下,JSON表达式: 一个人的信息可能有姓名、年龄、住址等信息。如何用一个对象来表达呢,可能很多人想到的是类,结构体。 但麻烦,利用上面js的特性,这样定义吧: var userinfo = { name:"张三",age:21,address:"火星"} 好了,这个用户信息建议完成。这个{}内(包括花括号)就是一个JSON表达式。 如果用呢,取姓名:userinfo.name,修改年龄:userinfo.age=23;。多方便啊,使用起来就如同结构体一样。还可以理解为hash表:key-value。 同样如果不需要某属性,可以delete userinfo.address,添加的话也可以userinfo[“phone”] = “123456”;
回过头来看上面创建类后添加方法的“方式三”,好象等号后面就是一个JSON表达式吧,只不过冒号后面的不是一般值,而是一个函数定义(函数也可以赋值的哦)。 所以,方式三是个类吗?伪类么。用词真好。
|
好了,类创建好了后,来理解方法:
2. var jQuery = function (obj) {
3. returnnew jQuery.fn.init(obj,null);
4. }
这个是创建一个jQuery类,同时又带上了函数,所以这里的函数你可以理解为构造函数。
看这第3行,构造函数中,直接return new了另一个对象,这个对象是什么jQuery.fn.init我们知道这个init是我们在上面jQuery下的嵌套类fn下创建的一个函数,怎么又变成new 后面的一个对象了?记住“伪类” 这个函数也可称之为类。那看下这函数做了什么事:
6. init: function (selector,context) {
7. obj=document.getElementById(selector.substring(1));
8. returnthis;
9. }
这个函数中,先跟据传入的ID值,获取对象,记录在obj中,然后返回this。
所以我们可以这样理解returnnew jQuery.fn.init(obj,null); 这个创建并得到的类就是init这个嵌套类,它属于jQuery.fn其下。
好了我们总的再想一想,当我们用jQuery(“#sp”)这样获取对象时,此时并不等同于document.getElementByID(“sp”),而是返回了一个jQuery.fn.init类。
好了,构造函数看明白了,再看看这个extend函数:
13. jQuery.extend =jQuery.fn.extend = function () {
14. for (name in arguments[0]) {
15. this[name] =arguments[0][name];
16. }
17. returnthis;
18. };
这个函数是做什么用的,主要看到第15行,结合上面讲的方式二,这个好像是在给一个对象添加函数吧。
再看这个函数是没有参数的,其实在javascript中,函数可以不写参数,但在函数中可以用arguments关键字来获取调用时的参数。即调用extend时可以写若干个参数。
那添加什么函数呢,看看这段代码:
19. jQuery.fn.extend({
20. Html: function (value) {
21. obj.innerHTML = value;
22. returnthis;
23. },
24. Hide: function () {
25. obj.style.display = "none";
26. returnthis;
27. }
28. });
第20~23在定义一个Html的函数,24~27在定义一个Hide函数,然后把这个函数又当成参数传入到extend函数中,这样就把这两个函数添加到jQuery.fn对象中了。看20~27又是在定义一个JSON表达式。
所以上面第14行arguments[0]就是拿到了这个JSON值,通过遍历,就可以拿到里面所有的对象与值,用C#中的hashtable来理解吧。
好了,想通了这样,就是知道了对象如何创建,并且也知道了是什么类型,但又看了下代码,发现,这个init中好像并没有添加什么Html()函数么,刚看的Html函数是添加到了jQuery.fn中了么。所以如果是C#中是不是考虑继承,即init类继承jQuery.fn类,这样不就有父类的方法属性了么,看下这句写法:
12. jQuery.fn.init.prototype =jQuery.fn;
prototype称为原型,可以理解为类的抽象意义。
同样,下面这29~34行,可以看到是jQuery下的extend,那就是添加到jQuery对象下,从前面创建时可以看出,如果有对象时并没有返回这个JQuery对象,所以这个可以理解为JQuery下的静态函数:
29. jQuery.extend({
30. style: function (elem,name, value) {
31. elem.style[name]= value;
32. alert("静态方法调用");
33. }
34. });
最后,讲到现在发现,我们用起来都是用$(“”),而并没有用JQuery(“”),当然后都也是可以用的。如何处理的呢,看这段:
35. window.jQuery = window.$ =jQuery;
前面我们说到,函数是可以赋值的,所以最后把$赋值为jQuery,使用$也是一个可用的函数名,等同于jQuery。
通过这样分析后,相信,基本上这个框架也比较清晰了,然后其他的代码无非就是住里面一些函数。大家可以看jQuery.fn.extend添加了类函数,jQuery.extend添加了静态函数。添加N多个后,就形成了jQuery库。当然里面还有涉及到event,这里没有深入,等以后深入看后,再来写写。
总结:
边学边看jQuery后,有着两大感触:
1.可能看了这代码后,有人跟一开始想法一样,写这么复杂,不就是类、函数、静态函数么,简单一定义,不也就实现了么,何必要这么绕,又是子类,又是嵌套类,又是用这个类创建后返回另一个类。
其实除这个外,看到大多数老外大牛们写的代码都这样,复杂,绕,这并不是在显摆,这里肯定有很多是我等水平人所无法体会的层次。正如刚写程序的人在看到设计模式一样,搞那么多类,累。
所以表面上看懂了这段代码,但深入的理念还难以领悟。
2. 回头看一下,这个javascript 应该说是一个非常漂亮的语言,里面处处都流露出其中的美,艺术感。想比C# java来讲,的确有不少的优越性。
By 烈火青春
2013-01-24 21:35