javascript 的面向对象特性参考
最近在看用javascript+css实现rich client。javascript 也是一个蛮有意思的语言。特别是其面向对象的实现和其他“标准”的OO launguage有很大的不同。但是,都是动态语言,我还是觉得它比起python语法和库都差得太远。可是没有explorer支持python开发 啊。。。:(
这是我学习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的调用也是如此。那么子类如何想调用父类的方法应怎么办呢?好像没有什么办 法哦,谁知道可以告诉我。但面向对象的理论告诉我们,继承主要是提供接口而不是代码复用,所以还是少有这样的念头为好 :)。
下面是一个例子程序。包含上面的所有的概念。
例子
///define: Cricle//
function Circle(r) {
this.r = r;
}
Circle.PI = 3.14;
Circle.prototype.PI = 3.14;
Circle.prototype.area = function() { return Circle.PI*this.r*this.r; }
Circle.prototype.area2 = function() { return this.PI*this.r*this.r; }
test
c = new Circle(3);
//alert("area1 :"+c.area());
//alert("area2 :"+c.area2());
Circle.max = function(a, b) { return a.r>b.r ? a.r : b.r; }
//alert("max is "+Circle.max(new Circle(1), new Circle(3)));
c1 = new Circle(1);
c2 = new Circle(1);
c2.PI = 100;//Circle.prototype.PI=100;
//alert("c1.area1 "+c1.area());
//alert("c1.area2 "+c1.area2());
//alert("c2.area1 "+c2.area());
//alert("c2.area2 "+c2.area2());
define: SubCircle //
function SubCircle(x, y, r) {
this.x = x;
this.y = y;
this.r = r;
}
SubCircle.prototype = new Circle(0);
SubCircle.prototype.PI = 100;
SubCircle.prototype.move2 = function(x, y) { this.x = x; this.y = y;}
SubCircle.prototype.area = function() { return this.PI*this.r*this.r*this.r; }
test
sc = new SubCircle(0,0,2);
alert(sc.area());
javascript 的面向对象特性参考相关推荐
- JavaScript的面向对象特性
JavaScript的面向对象特性 JavaScript是基于对象和事件驱动并具有安全性能的脚本:JavaScript虽然不是面向对象的编程语言但具有很多面向对象的特性. 1.面向对象开发 a) ...
- prototype.js 让你更深入的了解javascript的面向对象特性
js是一门很强大的语言,灵活,方便. 目前我接触到的语言当中,从语法角度上讲,只有 Ruby 比它更爽. 不过我接触的动态语言只有: js ruby python flash的as 简单的几门, 应该 ...
- Javascript面向对象特性
JavaScript面向对象的支持 ~~~~~~~~~~~~~~~~~~ 很少有人对JavaScript的面向对象特性进行系统的分析.我希望接下来的文字让你了解到这 个语言最少为人知的一面. 1. J ...
- 浅谈面向对象的javascript几个特性
javascript中的this和new javascript是一门很灵活的语言,尤其是function.他即可以以面向过程的方式来用,比如: function getName() {return ' ...
- JavaScript高级 面向对象、正则表达式
JavaScript高级 面向对象.正则表达式 学习目标: 理解面向对象开发思想 掌握 JavaScript 面向对象开发相关模式 掌握在 JavaScript 中使用正则表达式 typora-cop ...
- JavaScript之面向对象与原型笔记整理--------创建对象之原型(2)
4.原型 每个函数都有一个prototype属性,这个属性是一个对象,用途是包含可以由特定类型的所有实例共享的属性和方法. 逻辑上可以这么理解:prototype通过调用构造函数而创建的那个对象的原型 ...
- JavaScript是面向对象还是基于对象
与其他语言相比,JavaScript中的对象总是显得不是那么合群. 我们在学习JavaScript面向对象时,往往也会有疑惑: 为什么JavaScript知道ES6才有对象的概念,但是却没有像其他语言 ...
- JavaScript的函数式特性
前言 作为一门面向对象的语言,JavaScript本身却具有明显的函数式语言特征.而这也是很多JavaScript的支持者钟爱它的原因之一 – 函数式特性为这门语言带来了极大的灵活性.高阶函数.偏函数 ...
- 深入理解JavaScript的闭包特性如何给循环中的对象添加事件
初学者经常碰到的,即获取HTML元素集合,循环给元素添加事件.在事件响应函数中(event handler)获取对应的索引.但每次获取的都是最后一次循环的索引.原因是初学者并未理解JavaScript ...
最新文章
- H3C S5120-52P-WiNet交换机配置
- 转 .NET 2.0 SqlDependency快速上手指南
- 特征选择 回归_如何执行回归问题的特征选择
- linux spring mvc tomcat配置,Spring MVC配置详解
- Python2.x还是3.x?
- JavaScript 5/30:Flex Panel Gallery即FLEX布局的图片库
- DTC精彩回顾—王义成:国产数据库技术发展的探索与思考
- Oracle 12c 新特性:SQL Plan Directives与过量的动态采样解析
- python的认识从唯物主义_你对唯物主义的看法是怎么样的?
- (转载)构建public APIs与CORS
- 京东助手+淘宝试用助手+苏宁试用助手软件
- 如何建立复杂城市排水系统模型?基于SWMM与城市内涝一维二维耦合模型的复杂排水系统建模/城市排涝/海绵城市技术
- 像中文的罗马音字体复制_帮我把日语的罗马音弄成汉字!
- 微信公众号发送红包(源码)
- 软件观念革命:交互设计精髓_UI设计师、交互设计师、产品经理必备软件技能之Sketch...
- 【3】计算机原理-显卡工作模型
- 基于用户的产品分析之Cohort Analysis(群组分析,留存分析)
- 熬夜肝了这一份C++开发详细学习路线
- 苹果屏幕尺寸_2020年,没有小屏幕手机!
- HTML-input标签事件监听
热门文章
- Google App Engine(GAE)入门教程翻译
- grails 转为java_创建一个grails项目,然后转成maven项目
- IPv6 — IPv4v6 综合组网技术
- Linux 操作系统原理 — 系统启动流程
- 【转】清理Visual Studio打开的项目和文件、查找和最近引用组件痕迹
- asp mvc @Html.CheckBox(sel,true) 往后台传值问题
- 《Linux From Scratch》第三部分:构建LFS系统 第六章:安装基本的系统软件- 6.47. Gawk-4.1.1...
- 在一个JSP页面中包含另一个JSP页面的三种方式
- 传说中的裸奔节--认识及体验CSS
- Redis介绍使用及进阶