JavaScript类的设计
【转载】
Javascript与其他的面向对象语言不同,如C++,Java或PHP等。它并不是基于类的,而是基于原型的一种语言。
1、对象创建
在Javascript中创建一个类是非常容易的:
var myObject = {
aVar: 15,
aMethod: function() {
alert("I'm a method of the object myObject." + "aVar: " + this.aVar);
}
}
你不必通过定义一个类然后实例化该类来创建一个对象。我们在这里使用了一个对象构造器。它满足了使用单个对象的场合。如果我们需要使用同一个类型的多个对象,我们必须使用一个构造器函数和new关键字。
2、使用构造器函数
在Javascript中没有类的概念,但是构造器是存在的。你可以编写一个函数,然后通过new关键字来创建一个对象。
// 首先,我们为我们的类定义一个空的构造器
function myClass() {
this.aVar = 15;
this.aMethod = function() {
alert("I'm a method of the object myObject.");
}
} // 创建类的实例
var A = new myClass(); // 显示 15
alert(A.aVar); // 第二个实例
var B = new myClass();
3、动态附加
怎么在Javascript实现OO编程?
恐怕最佳的方式就是充分利用prototype属性。
关于prototype比较基本的原理的理解是:当你用prototype编写一个类后,当你new一个新的object,浏览器会自动把prototype中的内容替你附加在object上。这样,通过利用prototype,你也就实现了类似OO的Javascript。
方法共享
你必须使用prototype对象:
// 我们定义了一个prototype对象的一个方法
myClass.prototype.sharedMethod = function() { alert("I'm a shared method") } // 显示我们的信息
A.sharedMethod(); // 相同的信息
B.sharedMethod();
在myClass定义中并没有一个名为sharedMethod的方法。Javascript会在myClass相关联的prototype对象中寻找与该方法名相同的方法,如果存在的话,Javascript则调用该方法。
在Javascript中,object就是个associative array。上面的例子讲到了一个function就是个类。当你编写如下function时,其实就是定义了一个类,该function就是他的构造函数。
function MyObject(name, size){
this.name = name;
this.size = size;
}
之后,你能方便的通过MyObject类的prototype属性来方便的扩充他。
比如,你能给他添加其他的属性和方法:
//通过prototype属性添加tellSize 方法
MyObject.prototype.tellSize = function()
{
return "size of "+this.name+" is "+this.size;
}
//通过prototype属性添加color 属性 MyObject.prototype.color = "red"; MyObject.prototype.tellColor = function()
{
return "color of "+this.name+" is "+this.color;
} var myobj1 = new MyObject("tiddles", "7.5 meters"); domDiv.innerHTML += myobj1.tellColor()+"<br /><br />";
你能想象,当你调用tellColor()方法后,结果是这样的:
color of tiddles is red
非常方便的是,prototype属性能动态添加。比如,你需要往MyObject中加入一个height属性,并希望其提供一个tellHeight()方法来获得height属性的值。你能在上面的代码后,继续添加如下的代码:
MyObject.prototype.height = "2.26 meters"; MyObject.prototype.tellHeight = function()
{
return "height of "+this.name+" is "+this.height;
}
之后,你能访问一下myobj1的tellHeight()方法,你能得到如下的结果:
height of tiddles is 2.26 meters
prototype的这些动态的特性看起来有些迷人,不过我倒是反而觉得有些凉飕飕的。确实,这些特性给你非常大的灵活性,能给予你runtime改动类属性和方法的能力。不过,稍微发掘一下,会有些不良的习惯产生。
首先,如果能动态添加属性和方法,那么非常容易让人想到,当我调用时,我想要调用的属性或方法存在不?这是个非常严肃的问题,如果当我们调用时根本没有该属性或方法,将可能导致我们的脚本down掉。
不过也有解决办法。比如,在上面的代码中,当还没有tellHeight()方法时,我们能如下编写代码避免发生错误:
if (myobj1.tellHeight)
{
domDiv.innerHTML += myobj1.tellHeight()+"<br /><br />";
}
注意,一定要在if语句中,不要加方法后面的那对(),否则,直接就down掉了。有兴趣的读者能打印一下,看看分别访问myobj1.tellHeight和myobj1.tellHeight()时有什么差别。
也许,你觉得这个是小意思。加个判断嘛,不就好了?
对,不过下面一个问题更令人头痛。
属性和方法在不在的问题简单,可是属性和方法变不变化的问题可就严重了。在不在我们能检测,变不变呢?比如,请看下面的代码:
function MyObject(name, size)
{
this.name = name;
this.size = size;
} MyObject.prototype.color = "red"; MyObject.prototype.tellColor = function()
{
return "color of "+this.name+" is "+this.color;
} var myobj1 = new MyObject("tiddles", "7.5 meters"); domDiv.innerHTML += myobj1.tellColor()+"<br /><br />"; MyObject.prototype.color = "green"; domDiv.innerHTML += myobj1.tellColor()+"<br /><br />";
该代码将产生如下结果:
color of tiddles is red
color of tiddles is green
请注意,你修改的是类MyObject的color属性。不过你惊奇的看到你之前实例化的对象myobj1的属性值竟然也变化了。天!如果你的项目代码是多人合作,那么,也许某个人会在编程时为了图一己之便,擅自修改你的类。于是,所有人的对象都变化了。于是,你们陷入了漫长的debug过程中。。。。。。
上面是属性,更有方法:
function MyObject(name, size)
{
this.name = name;
this.size = size;
} MyObject.prototype.color = "red"; MyObject.prototype.tellColor = function()
{
return "color of "+this.name+" is "+this.color;
} var myobj1 = new MyObject("tiddles", "7.5 meters"); domDiv.innerHTML += myobj1.tellColor()+"<br /><br />"; MyObject.prototype.color = "green"; MyObject.prototype.tellColor = function()
{
return "your color of "+this.name+" is "+this.color;
} domDiv.innerHTML += myobj1.tellColor()+"<br /><br />";
这段代码的结果是:
color of tiddles is red
your color of tiddles is green
问题来了。Javascript太灵活的编程方式多少让人不适应。如果整个Team的水平都比较高还能,没人会犯这样的错误。不过,当有个毛头小伙子不知情,擅自修改类,将导致所有的人的对象都发生变化,无论是属性还是方法。在Javascript代码变得越来越多的Ajax时代,这是个严重的问题。
这说明,编写Javascript时,好的编程风格更加重要。记得某人原来说过这样的话,想Java和C#这些比较严格的语言,虽然降低了灵活性,但也减少了犯错误的可能。这样,即使一个新手,他写出的代码也不会和高手差太多。不过,像Javascript这样的脚本语言,由于太灵活,所以,高手写出的是天使,而新手写的,可能是魔鬼!
JavaScript类的设计的更多相关文章
- 第九章:Javascript类和模块
(过年了,祝大家新年好!) 第6章详细介绍了javascript对象,每个javascript对象都是一个属性集合,相互之间没有任何联系.在javascript中也可以定义对象的类,让每个对象都共享某 ...
- javascript 继承机制设计思想
作者: 阮一峰 原文链接:http://www.ruanyifeng.com/blog/2011/06/designing_ideas_of_inheritance_mechanism_in_java ...
- JavaScript “类”定义 继承 闭包 封装
一.Javascript “类”: 类:在面向对象编程中,类(class)是对象(object)的模板,定义了同一组对象(又称"实例")共有的属性和方法. Javascript是一 ...
- javascript的api设计原则
前言 本篇博文来自一次公司内部的前端分享,从多个方面讨论了在设计接口时遵循的原则,总共包含了七个大块.系卤煮自己总结的一些经验和教训.本篇博文同时也参考了其他一些文章,相关地址会在后面贴出来.很难做到 ...
- JavaScript 类式继承与原型继承
交叉着写Java和Javascript都有2年多了,今天来总结下自己所了解的Javascript类与继承. Javascript本身没有类似Java的面向对象的类与继承术语,但其基于原型对象的思想却可 ...
- 一种JavaScript 类的设计模式
一种JavaScript 类的设计模式尽管前面介绍了如何定义一个类,如何初始化一个类的实例,但既可以在function定义的函数体中添加成员,又可以用prototype 定义类的成员,代码显的很混乱, ...
- Unity3D 游戏开发构架篇 ——角色类的设计与持久化
在游戏开发中,游戏角色占了很大的篇幅,可以说游戏中所有的内容都是由主角所带动.这里就介绍一下角色类的设计和持久化. 一.角色类应用场景和设计思想 游戏中的角色类型不一而足,有不同的技能,有不同的属性等 ...
- “乐”动人心--2017年10款最佳音乐类APP设计盘点
在上下班的路上,听几首自己喜欢的音乐来打发无聊的等公交车和地铁的时间是现代年轻人的常态.音乐作为最能鼓动人心的"语言",也成为了人们在互联网生活里占比例最高的消费活动之一,一款好看 ...
- Java SE 之 数据库操作工具类(DBUtil)设计
JDBC创建数据库基本连接 //1.加载驱动程序 Class.forName(driveName); //2.获得数据库连接 Connection connection = DriverManager ...
随机推荐
- Oracle11g x64使用Oracle SQL Developer报错:Unable to find a Java Virtual Machine
原因oracle 11g中安装的Oracle SQL Developer是32位的,而我们现在给他指定的java.exe却是64位的,所以会出现这种错误.解决方法1)从网上下载Oracle SQL D ...
- js将对象转成字符串-支持微信
最近写一个微信项目时用到了 把对象转成字符串,因为我需要把它存在cookie中,碰到了一些问题,在这里分享一下. 要转换的就是这货~ var FBinf = { "workPlacesCod ...
- Spark IDEA开发环境构建
本文档基于IEDA构建spark maven应用. date: 2016/8/1 author: wangxl 1.下载IDEA https://www.jetbrains.com/idea/ 2.安 ...
- (转)创建和查看Javadoc文档
原地址:http://jinnaxu-tju-edu-cn.iteye.com/blog/667177 Javadoc是Sun公司提供的一个技术,它从程序源代码中抽取类.方法.成员等注释形成一个和源代 ...
- jq里attr和prop的区别
jquery中attr和prop的区别 在高版本的jquery引入prop方法后,什么时候该用prop?什么时候用attr?它们两个之间有什么区别?这些问题就出现了. 关于它们两个的区别,网上的答 ...
- float的理解
1.浮动包裹性——浮动具有让元素按displya:inline-block显示(如果没有设置宽度和高度,则它可以显示的尽量窄高 度尽量小).2.浮动破坏性——浮动元素漂浮在标准流之上(但没有脱离文档流 ...
- Linux 下配置 SoftEther Client
我经常使用的代理有 SSH, GoAgent, FreeGate, VPN, HttpProxy 等等,不过 SoftEther 应该是我用过的最快.最稳定的 VPN 协议. Windows 下配置 ...
- 基于cygwin构建u-boot(一)环境搭建
从本文开始,更系统的描述基于cygwin构建u-boot. 之前<痛苦的版本对齐>系列,对于cygwin环境下Sourcery CodeBench,u-boot-1.1.6的构建有侧面的说 ...
- 龙邱STM32单片机用J-LINK下载无法被识别的解决方法
问题如下: 按照正常步骤使用keil5给龙邱的stm32下载程序,SWD下载方式提示no cortex-m sw device found,JTAG方式提示no cortex-m device fou ...
- robot自动化测试(一)---安装
1.安装python 百度搜索安装程序即可:我安装的python 2.7.6 64位 2.安装wxpython 版本:wxPython2.8 下载地址:http://sourceforge.net/p ...