javascript 的面向对象特性参考

所属分类: 网络编程 / JavaScript 阅读数: 1530
收藏 0 赞 0 分享

javascript 的面向对象特性参考。
这是我学习javascript中面向对象特性的一点总结。希望对具有其他语言的面向对象设计经验的朋友理解javascript的OO有所帮助。我具有c++,java和python的面向对象设计的经验。
总的感受, javascript作为一种弱类型的动态语言,语法解决于java,但其面向对象的方式更和python相识。
1 面向对象的特性
类,成员变量,成员函数,类变量,类方法,继承,多态
1) 类
类的定义:function Circle(r) {        this.r = r; }
类的实例化: c = Circle(3);
2)成员变量
成员变量在初始化函数里申明:this.r = r;  
注意,在对象生成后,你也可以给它附上成员变量,比如c.name="my circle",
但是除非特别的需要,我强烈建议你不要这样做。也就是所有的成员都应在初始化函数里声明。我认为这是一种好的style。
这一点和python很相识。
3)成员函数
成员函数的标准形式是这样的:
Cricle.prototype.area = function() { return 3.14 * this.r * this.r; }
这和java或python或c++都大不一样。但为了帮助理解,你可以把prototype看作基类。
prototype里面的变量或方法,是所有对象共享的。
比如,c.area()调用最终就会让解释器调用到Circle.prototype.area().
相比于java和c++,javascript具有他们都没有的一个语义,也就是你可以在prototype里定义变量。定义在prototype里的变量可以被所有的实例共享量。所以一般它应该是一个常数,比如:Circle.prototype.PI = 3.14.
显然,prototype里的变量和方法都应该是不变的。每一个对象实例都不应该取修改prototype中的内容。虽然语言允许你可以这样做,但这样做没有任何意义,也违反了面向对象的语义(想想,java会让你动态修改一个类的方法吗)。
当然,对于多态是另外一回事,在后面详述。
而且,我建议所有的成员函数都在紧接类定义的地方定义。而不应该在代码运行的某个地方对一个对象实例增加/修改成员函数。这样的结果是javascript的类定义尽量向java看齐。使得代码更清晰。
4)类变量
类变量是属于一个类的变量。就像java里用static修饰的变量。因为它属于类,所以它也应该是一个常量。实例不应该去修改它,虽然你可以(java里可以用final修饰,使得类变量一旦定义,就不能修改)。
这里可以看到,类变量和prototype里定义的变量的功能是相似的。确实如此,他们的目的都是一样的。但他们的访问方式
不一样。比如:
Circle.prototype.PI = 3.14;
Circle.PI = 3.14;
//用prototype里的变量
Circle.prototype.area1 = function() { return this.PI * this.r * this.r; }
//用类变量
Circle.prototype.area2 = function() { return Circle.PI * this.r * this.r; }
5)类方法
这个概念应该很简单。注意类方法里绝对不要用this关键字,和java完全一样。
Circle.max = function(a, b) { return a.r > b.r ? a : b; }
theMax = Circle(new Circle(1), new Circle(4));
6)继承
子类继承父类,那么 “子类实例” 具有和 “父类实例” 完全一样的行为。javascript是这样实现的。
function SubCircle(x, y, r) { this.x = x; this.y = y; this.r =r; }
SubCircle.prototype = new Circle(0);
记得前面说的吗?可以把prototype看作一个基类。这里,prototype确确实实是一个基类。它是如何实现的呢?
举例如下:sc = SubCirlce(1,1,3); sc.area();
调用的传递: sc.area()->sc.prototype.area()->Circle(0).area()->Circle.prototype.area().看来是不是很奇妙呢。
通过这种方式,javascript实现了继承。
7)多态
多态是子类会定义和父类具有相同signature的方法。假设在SubCircle所在的空间PI=100,而面积公式也变为 PI*R*R*R。
SubCircle.prototype.PI = 100
SubCircle.prototype.area = function() { return this.PI*this.r*this.r*this.r; }
Sc.area() 这样的操作可以认为是: 
Sc.PI->sc.prototype.PI->Cricle(0).PI = 100
Sc.area()->sc.prototype.area()->Circle(0).area. 
这个时候,调用过程是这样的
sc.area()->sc.prototype.area(),在这里解释器发现了area这个方法,于是它就调用此方法。
而Cricle.prototype.area就永远也不会被调用。PI的调用也是如此。
那么子类如何想调用父类的方法应怎么办呢?好像没有什么办法哦,谁知道可以告诉我。但面向对象的理论告诉我们,继承主要是提供接口而不是代码复用,所以还是少有这样的念头为好 :)。
下面是一个例子程序。包含上面的所有的概念。


[Ctrl+A 全选 注:引入外部Js需再刷新一下页面才能执行]

更多精彩内容其他人还在看

Angular使用Md5加密的解决方法

这篇文章主要介绍了Angular使用Md5加密的解决方法,需要的朋友可以参考下
收藏 0 赞 0 分享

详解JS构造函数中this和return

本文通过实例代码给大家介绍了JS构造函数中this和return,需要的朋友参考下吧
收藏 0 赞 0 分享

ES6中Array.find()和findIndex()函数的用法详解

ES6为Array增加了find(),findIndex函数。find()函数用来查找目标元素,找到就返回该元素,找不到返回undefined,而findIndex()函数也是查找目标元素,找到就返回元素的位置,找不到就返回-1。下面通过实例详解,需要的朋友参考下吧
收藏 0 赞 0 分享

JS闭包的几种常见形式实例详解

本文通过实例代码给大家详细介绍了js闭包的几种常见形式,代码简单易懂,非常不错,具有参考借鉴价值,需要的朋友参考下
收藏 0 赞 0 分享

ES6中Array.copyWithin()函数的用法实例详解

ES6为Array增加了copyWithin函数,用于操作当前数组自身,用来把某些个位置的元素复制并覆盖到其他位置上去。下面重点给大家介绍ES6中Array.copyWithin()函数的用法,需要的朋友参考下
收藏 0 赞 0 分享

Javascript 严格模式use strict详解

严格模式:由ECMA-262规范定义的JavaScript标准,对javascrip的限制更强。这篇文章主要介绍了Javascript 严格模式use strict详解 ,需要的朋友可以参考下
收藏 0 赞 0 分享

引入JavaScript时alert弹出框显示中文乱码问题

今天在HTML中引入JavaScript文件运行时,alert弹出的提示框中文显示为乱码,怎么解决此问题呢?下面小编给大家带来了引入JavaScript时alert弹出框显示中文乱码问题的解决方法,一起看看吧
收藏 0 赞 0 分享

AngularJs 延时器、计时器实例代码

这篇文章主要介绍了AngularJs 延时器、计时器实例代码,需要的朋友可以参考下
收藏 0 赞 0 分享

JS分页的实现(同步与异步)

这篇文章主要介绍了JS分页的实现(同步与异步),需要的朋友可以参考下
收藏 0 赞 0 分享

Angularjs自定义指令实现分页插件(DEMO)

由于最近的一个项目使用的是angularjs1.0的版本,涉及到分页查询数据的功能,后来自己就用自定义指令实现了该功能,下面小编把实例demo分享到脚本之家平台,需要的朋友参考下
收藏 0 赞 0 分享
查看更多