来自:http://www.nowamagic.net/javascript/js_RelationOfFunctionAndObject.php
在ajax兴起以前,很多人写JavaScript可以说都是毫无章法可言的,基本上是想到什么就写什么,就是一个接一个的函数function,遇到重复的还得copy,如果一不小心函数重名了,还真不知道从何开始查找错误,因为大家总是用面向过程的编程思想来写JavaScript代码,而且也由于网络上充斥了太多小“巧”的JavaScript代码段,很多都是随意而为,很不规范,这也就造成了大家对JavaScript的“误解”,一味的认为它就是一个辅助的小东东,而不适合做大的东西开发。但是自从ajax兴起后,大量的JavaScript代码编写要求人们具备像写Java类似的代码一样,能够面向对象进行开发。
所以下面就结合我自己的体会和所学习的东东和大家一起来学习在JavaScript中如何使用面向对象的编程。其实使用JavaScript进行面向对象开发也不是很难的事情,因为在JavaScript中每一个function就是一个对象,比如下一个函数:
1 |
function HelloWorld() { |
那么我们在使用的时候就可以把它当成一个对象来使用,比如使用如下的测试函数:
2 |
var obj = new HelloWorld(); |
那么在调用_test方法后就会弹出hello world!的提示框,也就是调用了HelloWorld()对象(函数)。在这里HelloWorld这个对象没有任何属性和方法,它只有一个构造方法HelloWorld(),我们可以把它想象成JAVA中的一个没有任何属性和方法的类,当使用new进行对象创建的时候,就调用了它的构造方法。这也是我们最简单的对象了,当然了,一个对象肯定是要赋予它属性和方法的,在JS中我们使用prototype原型关键字进行赋值,比如我要给HelloWorld对象增加一个sayHello方法和一个name属性,那么就可以这样添加:
1 |
HelloWorld.prototype = { |
3 |
sayHello : function () { |
那么就可以为HelloWorld添加了一个name属性和sayHello方法,我们再改一下_test方法,如下:
2 |
var obj = new HelloWorld(); |
调用_test方法后就会先后打印hello wordl!和JavaScript(一个是构造方法中的alert,一个是sayHello方法中的alert)。注意sayHello方法中的alert引用了this关键字,该关键字表示的就是HelloWorld对象,即默认指向该对象,和JAVA中的this关键字一样。对于向一个对象添加实例方法和属性,我们可以采用上述的方式,即使用prototype关键字进行赋值,格式如下:
04 |
方法一 : function (参数列表) { |
07 |
方法二 : function (参数列表) { |
可以按照如上方式对一个对象进行多个属性和方法的定义,这样在new一个对象后,就可以使用实例名称.属性或方法来获取属性或执行方法了。
在上面的方法中,大家不知道发现没有对象的属性是可以直接访问的,比如访问HelloWorld对象的name属性就可以使用obj.name直接获取。这就好比我们JAVA中的公有属性了,而且我们还可以直接对name属性进行赋值操作。所以现在有一个问题了,我们如何给一个对象赋一个私有成员变量呢?那我们就可能要改一下HelloWorld类的声明方式了,不使用prototype进行类的属性和方法声明,而是直接使用内嵌函数和属性进行声明,修改的HelloWorld如下,我们命名为HelloWorld2:
1 |
function HelloWorld2() { |
2 |
var privateProp = 'hello world 2!' ; |
3 |
this .method = function () { |
看到HelloWorld2的类申明方式了没?是直接在函数内部进行了函数嵌套申明,而且我们还设置了一个局部变量privateProp,即我们的私有成员变量,该变量只能被HelloWorld2内部的函数进行访问,外部访问是不允许的,这样我们就可以通过使用变量的作用域来巧妙的设置类的私有变量了。我们应用如下:
2 |
var obj2 = new HelloWorld2(); |
3 |
obj2.method(); // 调用该方法将打印'hello world 2! |
4 |
alert(obj2.privateProp); // 将打印undefined |
上面所说的都是如何定义一个类,以为如何为一个类定义属性和方法,由于采用prototype方式进行定义清晰明了,所以一般都是使用该方式进行类的定义,而且现在很多AJAX框架中都使用了类似的类声明方式。而且类的私有成员变量却只能在类的构造方式中的函数进行访问,这样类的prototype声明的方法就不能访问该私有成员变量了,而且可读性方面也没有prototype方式好。
好了,上面所说的都是定义一个类的实例方法和属性。在JAVA中类有实例方法和属性与类方法和属性之分。所谓类属性和方法就是该类的所有实例都只维护一份类属性和类方法的副本,而不是每个实例都维护一套,这和实例属性和实例方法是不一样的。那么在JS中如何为一个类定义静态类方法和类属性呢?我们可以直接为类添加静态属性和静态方法,比如为HelloWorld类添加一个age的静态属性和一个hello的静态方法,那么声明如下:
2 |
HelloWorld.hello = function () { |
那么这样就为类HelloWorld声明了静态属性age和静态方法hello了。在使用的时候就直接使用类名进行访问了,但是不能使用实例进行访问,这点与JAVA中的是一致的,测试如下:
2 |
var obj = new HelloWorld(); |
3 |
obj.sayHello(); // 正确,实例方法,可以通过实例进行访问 |
4 |
HelloWorld.hello(); // 正确,静态方法,通过类名进行直接访问 |
5 |
obj.hello(); // 错误,不能通过实例访问静态方法。会报JS错误! |
- 了解Javascript中函数作为对象的魅力
前言 Javascript赋予了函数非常多的特性,其中最重要的特性之一就是将函数作为第一型的对象.那就意味着在javascript中函数可以有属性,可以有方法, 可以享有所有对象所拥有的特性.并且最重 ...
- javascript中函数声明、变量声明以及变量赋值之间的关系与影响
javascript中函数声明.变量声明以及变量赋值之间的关系与影响 函数声明.变量声明以及变量赋值之间有以下几点共识: 1.所有的全局变量都是window的属性 2.函数声明被提升到范围作用域的顶端 ...
- 改变JavaScript中函数的内部this指向!
改变JavaScript中函数的内部this指向! 第一种方法 call call 可以 调用函数 + 改变函数内的this指向! var obj = { name: 'lvhang' } funct ...
- JavaScript中函数函数的定义与变量的声明<基础知识一>
1.JavaScript中函数的三种构造方式 a.function createFun(){ } b.var createFun=function (){ } c.var createFun=new ...
- JavaScript中的事件对象
JavaScript中的事件对象 JavaScript中的事件对象是非常重要的,恐怕是我们在项目中使用的最多的了.在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含这所有与事件有 ...
- JavaScript中__proto__与prototype的关系
一.所有构造器/函数的__proto__都指向Function.prototype,它是一个空函数(Empty function) 1 2 3 4 5 6 7 8 9 Number.__proto__ ...
- Javascript中函数的四种调用方式
一.Javascript中函数的几个基本知识点: 1.函数的名字只是一个指向函数的指针,所以即使在不同的执行环境,即不同对象调用这个函数,这个函数指向的仍然是同一个函数. 2.函数中有两个特殊的内部属 ...
- JavaScript中创建字典对象(dictionary)实例
这篇文章主要介绍了JavaScript中创建字典对象(dictionary)实例,本文直接给出了实现的源码,并给出了使用示例,需要的朋友可以参考下 对于JavaScript来说,其自身的Array对象 ...
- Javascript学习1 - Javascript中的类型对象
原文:Javascript学习1 - Javascript中的类型对象 1.1关于Numbers对象. 常用的方法:number.toString() 不用具体介绍,把数字转换为字符串,相应的还有一个 ...
随机推荐
- C++中执行windows指令
执行windows指令: BOOL ExecDosCmd(]) { SECURITY_ATTRIBUTES sa; HANDLE hRead,hWrite; sa.nLength = sizeof(S ...
- ASP.net中导出Excel的简单方法介绍
下面介绍一种ASP.net中导出Excel的简单方法 先上代码:前台代码如下(这是自己项目里面写的一点代码先贴出来吧) <div id="export" runat=&quo ...
- 【C#】数据库备份及还原的实现代码【转载】
[转载]http://www.codesky.net/article/200908/128600.html C#数据库备份及还原1.在用户的配置时,我们需要列出当前局域网内所有的数据库服务器,并且要列 ...
- 短租app简析
本人应聘某短租app产品经理时做的材料,贴出来请高手指教. 所有内容来自公开资料,不涉及商业秘密.
- Spark Streaming揭秘 Day26 JobGenerator源码图解
Spark Streaming揭秘 Day26 JobGenerator源码图解 今天主要解析一下JobGenerator,它相当于一个转换器,和机器学习的pipeline比较类似,因为最终运行在Sp ...
- 源码编译安装LNMP环境及配置基于域名访问的多虚拟主机
实验环境及软件版本: CentOS版本: 6.6(2.6.32.-504.el6.x86_64) nginx版本: nginx-1.6.2 mysql版本: Mysql-5.6.23 php版本: ...
- wxPython 基本框架与运行原理 -- App 与 Frame
<wxPython in Action> chapter 1.2 笔记 wxPython 是 wxWidgets 的 Python 实现,“w” for Microsoft Windows ...
- Python执行效率测试模块timei的使用方法与与常用Python用法的效率比较
timeit模块用于测试一段代码的执行效率 1.Timer类 Timer 类: __init__(stmt="pass", setup="pass", time ...
- HashMap加入数据后,会自动根据首字母排序
1.Map<String, ArrayList<XX>> entityHashMap = new HashMap<>(); 然后增加一些数据,会发现根据String ...
- android.support.v7.app.AppCompatActivity
1.Android Studio (api 23) 新建项目的时候 Activity public class MainActivity extends AppCompatActivity 2.系统默 ...