学习javascript并解读JQuery

学习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")classMyClass”);

 

分析:

上面第1JQuery中,$(“#sp”)为获取对象类创建一个JQuery类,然后立即调用Html函数。

上面第2JQuery中,$.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 结构相同,其下有方法initobj属性

13.           jQuery.extend =jQuery.fn.extend = function () {      

这段代码采用了方式一,在jQueryjQuery.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表达式。

所以上面第14arguments[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

 

 

 

 

原文地址:https://www.cnblogs.com/zjfstudio/p/3764714.html