JavaScript中函数与对象的微妙关系

一个function就是一个对象
服务器君一共花费了431.389 ms进行了6次数据库查询,努力地为您提供了这个页面。
试试阅读模式?希望听取您的建议

在ajax兴起以前,很多人写JavaScript可以说都是毫无章法可言的,基本上是想到什么就写什么,就是一个接一个的函数function,遇到重复的还得copy,如果一不小心函数重名了,还真不知道从何开始查找错误,因为大家总是用面向过程的编程思想来写JavaScript代码,而且也由于网络上充斥了太多小“巧”的JavaScript代码段,很多都是随意而为,很不规范,这也就造成了大家对JavaScript的“误解”,一味的认为它就是一个辅助的小东东,而不适合做大的东西开发。但是自从ajax兴起后,大量的JavaScript代码编写要求人们具备像写Java类似的代码一样,能够面向对象进行开发。

所以下面就结合我自己的体会和所学习的东东和大家一起来学习在JavaScript中如何使用面向对象的编程。其实使用JavaScript进行面向对象开发也不是很难的事情,因为在JavaScript中每一个function就是一个对象,比如下一个函数:

function HelloWorld() {
    alert('hello world!');
}

那么我们在使用的时候就可以把它当成一个对象来使用,比如使用如下的测试函数:

function _test() {
    var obj = new HelloWorld();
}

那么在调用_test方法后就会弹出hello world!的提示框,也就是调用了HelloWorld()对象(函数)。在这里HelloWorld这个对象没有任何属性和方法,它只有一个构造方法HelloWorld(),我们可以把它想象成JAVA中的一个没有任何属性和方法的类,当使用new进行对象创建的时候,就调用了它的构造方法。这也是我们最简单的对象了,当然了,一个对象肯定是要赋予它属性和方法的,在JS中我们使用prototype原型关键字进行赋值,比如我要给HelloWorld对象增加一个sayHello方法和一个name属性,那么就可以这样添加:

HelloWorld.prototype = {
    name : 'JavaScript',
    sayHello : function() {
        alert(this.name);
    }
}

那么就可以为HelloWorld添加了一个name属性和sayHello方法,我们再改一下_test方法,如下:

function _test() {
    var obj = new HelloWorld();
    obj.sayHello();
}

调用_test方法后就会先后打印hello wordl!和JavaScript(一个是构造方法中的alert,一个是sayHello方法中的alert)。注意sayHello方法中的alert引用了this关键字,该关键字表示的就是HelloWorld对象,即默认指向该对象,和JAVA中的this关键字一样。对于向一个对象添加实例方法和属性,我们可以采用上述的方式,即使用prototype关键字进行赋值,格式如下:

对象名称.prototype = {
    属性一 : 属性值,
    属性二 : 属性值,
    方法一 : function(参数列表) {
        方法体;
    },
    方法二 : function(参数列表) {
        方法体;
    }
}

可以按照如上方式对一个对象进行多个属性和方法的定义,这样在new一个对象后,就可以使用实例名称.属性或方法来获取属性或执行方法了。

在上面的方法中,大家不知道发现没有对象的属性是可以直接访问的,比如访问HelloWorld对象的name属性就可以使用obj.name直接获取。这就好比我们JAVA中的公有属性了,而且我们还可以直接对name属性进行赋值操作。所以现在有一个问题了,我们如何给一个对象赋一个私有成员变量呢?那我们就可能要改一下HelloWorld类的声明方式了,不使用prototype进行类的属性和方法声明,而是直接使用内嵌函数和属性进行声明,修改的HelloWorld如下,我们命名为HelloWorld2:

function HelloWorld2() {
    var privateProp = 'hello world 2!';
    this.method = function() {
         alert(privateProp);
    }
}

看到HelloWorld2的类申明方式了没?是直接在函数内部进行了函数嵌套申明,而且我们还设置了一个局部变量privateProp,即我们的私有成员变量,该变量只能被HelloWorld2内部的函数进行访问,外部访问是不允许的,这样我们就可以通过使用变量的作用域来巧妙的设置类的私有变量了。我们应用如下:

function _test2() {
    var obj2 = new HelloWorld2();
    obj2.method();   // 调用该方法将打印'hello world 2!
    alert(obj2.privateProp); // 将打印undefined
}

上面所说的都是如何定义一个类,以为如何为一个类定义属性和方法,由于采用prototype方式进行定义清晰明了,所以一般都是使用该方式进行类的定义,而且现在很多AJAX框架中都使用了类似的类声明方式。而且类的私有成员变量却只能在类的构造方式中的函数进行访问,这样类的prototype声明的方法就不能访问该私有成员变量了,而且可读性方面也没有prototype方式好。

好了,上面所说的都是定义一个类的实例方法和属性。在JAVA中类有实例方法和属性与类方法和属性之分。所谓类属性和方法就是该类的所有实例都只维护一份类属性和类方法的副本,而不是每个实例都维护一套,这和实例属性和实例方法是不一样的。那么在JS中如何为一个类定义静态类方法和类属性呢?我们可以直接为类添加静态属性和静态方法,比如为HelloWorld类添加一个age的静态属性和一个hello的静态方法,那么声明如下:

HelloWorld.age = 22;
HelloWorld.hello = function() {
    alert(HelloWorld.age);
}

那么这样就为类HelloWorld声明了静态属性age和静态方法hello了。在使用的时候就直接使用类名进行访问了,但是不能使用实例进行访问,这点与JAVA中的是一致的,测试如下:

function _test() {
    var obj = new HelloWorld();
    obj.sayHello();  // 正确,实例方法,可以通过实例进行访问
    HelloWorld.hello(); // 正确,静态方法,通过类名进行直接访问
    obj.hello(); // 错误,不能通过实例访问静态方法。会报JS错误!
}

本文地址:http://www.nowamagic.net/librarys/veda/detail/439,欢迎访问原出处。

不打个分吗?

转载随意,但请带上本文地址:

http://www.nowamagic.net/librarys/veda/detail/439

如果你认为这篇文章值得更多人阅读,欢迎使用下面的分享功能。
小提示:您可以按快捷键 Ctrl + D,或点此 加入收藏

大家都在看

阅读一百本计算机著作吧,少年

很多人觉得自己技术进步很慢,学习效率低,我觉得一个重要原因是看的书少了。多少是多呢?起码得看3、4、5、6米吧。给个具体的数量,那就100本书吧。很多人知识结构不好而且不系统,因为在特定领域有一个足够量的知识量+足够良好的知识结构,系统化以后就足以应对大量未曾遇到过的问题。

奉劝自学者:构建特定领域的知识结构体系的路径中再也没有比学习该专业的专业课程更好的了。如果我的知识结构体系足以囊括面试官的大部分甚至吞并他的知识结构体系的话,读到他言语中的一个词我们就已经知道他要表达什么,我们可以让他坐“上位”毕竟他是面试官,但是在知识结构体系以及心理上我们就居高临下。

所以,阅读一百本计算机著作吧,少年!

《浪潮之巅》 吴军 (作者)

近一百多年来,总有一些公司很幸运地、有意识或无意识地站在技术革命的浪尖之上。在长达十年甚至几十年的时间里,它们代表着科技的浪潮,直到下一波浪潮的来临。从19世纪末算起,AT&T公司、IBM公司、苹果公司、英特尔公司、微软公司、思科公司、雅虎公司和Google公司都先后被幸运地推到了浪尖。虽然,它们来自不同的领域,中间有些已经衰落或正在衰落,但是它们都极度辉煌过。吴军的这本《浪潮之巅》系统地介绍了这些公司成功的本质原因及科技工业一百多年的发展。在这些公司兴衰的背后,有着它必然的规律。《浪潮之巅》不仅讲述科技工业的历史,更重在揭示它的规律性。

更多计算机宝库...