演示OOP中的封装、继承在JavaScript中的书写方式(另附JS反射的例子)

演示OOP中的封装、继承在JavaScript中的书写方式(另附JS反射的例子)

 

 

最近几天都在尝试去理解学习老师演示的JS面向对象编程的例子,我细读这些例子之后,也终于找到了JS中运用Java中已掌握的面向对象编程方式去写JS代码的感觉了。于是,在老紫竹的世纪网上我也写了几篇帖子以演示最近的学习所得。

 

下面是这几天写的几篇帖子,整理一下给大家分享一下,希望过路的朋友能指正其中的错误,以帮助我更好地理解JS的OO思想。

 

一、演示OOP中的封装在JavaScript中的书写方式


在Java中书写Pojo已经是一件司空见惯的事情,当然,也是一件可以称之为“体力活”的事情。

今天,初初学习JS中的OOP,既然面向对象的三大特性是:封装、继承、多态,那么按照这个次序,
我便先弄弄JS中对象的封装。虽然是体力活,但还是需要去做。

以下便是我使用Java的Pojo书写方式来写JS的Pojo:

运行效果:

 

演示OOP中的封装在JavaScript中的书写方式



源码清单:

 

 

以上仅为个人学习JS面向对象编程的一个开端,如果有什么不正确的地方,还烦请各位指正为感!


By CodingMouse
2009年4月23日

 

二、演示JS中动态调用类中的方法(JS的反射机制)


原本计划是紧接着上一篇文章《
演示OOP中的封装在JavaScript中的书写方式 》之后 继续写JS的类继承,结果因为要在项目中将Ajax回调返回的XML自动映射为JavaScript的Pojo类(其中,Ajax的XML内容也是由Java的Pojo类自动映射生成的),但却因为无法动态调用JS的类方法而苦恼(在上篇文章中可以看到,调用JS类方法是使用点“.”操作符显式调用的,这样就必须知道类的方法名)。其实语言之间都有互通性,那么,我们能不能在JS中找到类似于Java反射的机制呢?答案是肯定的。我们将要用到平时我们书写普通的表单验证中很少见的eval()方法(在JS领域更贴切的说法是“函数”)。下面是在 w3School在线教程 上的JScript手册中查到的API:
JavaScript eval() 函数

定义和用法
eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码。

语法
eval(string)参数 描述
string 必需。要计算的字符串,其中含有要计算的 JavaScript 表达式或要执行的语句。

返回值
通过计算 string 得到的值(如果有的话)。

说明
该方法只接受原始字符串作为参数,如果 string 参数不是原始字符串,那么该方法将不作任何改变地返回。因此请不要为 eval() 函数传递 String 对象来作为参数。

如果试图覆盖 eval 属性或把 eval() 方法赋予另一个属性,并通过该属性调用它,则 ECMAScript 实现允许抛出一个 EvalError 异常。

抛出
如果参数中没有合法的表达式和语句,则抛出 SyntaxError 异常。

如果非法调用 eval(),则抛出 EvalError 异常。

如果传递给 eval() 的 Javascript 代码生成了一个异常,eval() 将把该异常传递给调用者。
提示和注释
提示:虽然 eval() 的功能非常强大,但在实际使用中用到它的情况并不多。
实例
例子 1
在本例中,我们将在几个字符串上运用 eval(),并看看返回的结果:

<script type="text/javascript">

eval("x=10;y=20;document.write(x*y)")

document.write(eval("2+2"))

var x=10
document.write(eval(x+17))

</script>输出:

200
4
27例子 2
看一下在其他情况中,eval() 返回的结果:

eval("2+3") // 返回 5
var myeval = eval; // 可能会抛出 EvalError 异常
myeval("2+3"); // 可能会抛出 EvalError 异常
可以使用下面这段代码来检测 eval() 的参数是否合法:

try {
alert("Result:" + eval(prompt("Enter an expression:","")));
}

catch(exception) {
alert(exception);
}


以上内容引用地址: JavaScript eval() 函数

w3School提供了在线的eval()函数测试工具,地址为:
eval()函数在线测试工具

通过上面的API和在线测试可以看得出来,eval()函数的这种动态特性正好与Java的反射机制不谋而合(当然,Java也有抄JS这种动态语言特性的嫌疑,至于到底谁抄谁的我也没去详细了解了,反正这种动态特性可以让我们写出更加灵活的程序)。

资料也查到了,也在线测试了,那么,让我们一起来完成本文的主题——JS动态调用类中的方法。

...

由于只是一个演示,所以我就不再将JS文件与HTML文件分离开来了,而且本次演示的主角也是JS。
以下是我完成的一段演示代码清单:

第一种方式(不使用eval()函数):
第二种方式(使用eval()函数动态执行类方法):

呵呵!是不是很有乐趣?将Java中的许多OO思想搬抄过来可以让你的的JS写得更加优美!

附件中依然也提供了这段简单的演示代码。欢迎批评指正!


By CodingMouse
2009年4月23日
三、演示OOP中的继承在JavaScript中的书写方式


在我写的前面两篇文章《
演示OOP中的封装在JavaScript中的书写方式 》以及《 演示JS中动态调用类中的方法(JS的反射机制) 》中,我已经为大家演示了使用Java的OO编程思想来学习JavaScript的面向对象编程中关于继承反射的书写方式。如果你已经掌握了Java的面向对象基础知识,那么,阅读我写的这几篇关于JavaScript的面向对象编程演示文章会感到特别轻松,而且也会觉得什么JavaScript的闭包(Closure)也就是那么回事(对于JS中的闭包,较为直观的解释是:当函数a的内部函数b被函数a外的一个变量引用的时候,就创建了一个闭包)。由于我这里的演示只是以Java的思考方式来学习JS面向对象编程,所以,不在这里过多阐述JS的概念。不过请记住一点,要实现域的作用范围控制,就需要合理地使用闭包。

也许你在其它网文上见到过一些演示JS继承的例子,但那些例子大多数是将类的所有公共方法(域)都使用原型(prototype)来构建。那么,作为习惯了Java的OO思维方式的你是比较难以接受的。那么,我的例子又有什么特点呢?让我们一起来看看下面这段例程:
呵呵!怎么样?是不是感觉很像Java的书写方式?

以上这段代码虽然还是使用的相对简单的原型(prototype)继承方式,但你可以看到,整个演示过程中prototype关键字只在代码中(注释除外)出现了一次,即指定其父类(PersonPojo)那一句:StudentPojo.prototype = new PersonPojo();,代码中我已经添加了详细的注释说明。

实质上,还有使用JS中的call方法和apply方法来实现的经典继承方式,由于这段时间很忙,且这种实现方式的编写要相对复杂些,我还得抽时间消化一下再给大家作演示。 


By CodingMouse
2009年4月25日
以上是近段时间学习JS面向对象编程的一些点滴,在看到众多书写方式的情况下,寻找和尝试一种适合自己的实现方式才是对自己有益的。看到别人写的东西,如果不自己不能在别人已有的基础上进行优化和改良,那么也就失去了学习的意义。特别是上面对于JS继承的书写方式,我在其它地方暂时还没有看到过(也许只是我没有看到过)。
总之觉得使用Java里面这种较纯净的面向对象的书写方式来学习JS是一种非常好的途径。虽然老师在教学过程中提供一些实例让学员们去理解,但最终还是有相当部分的学员表现出诸多的反对和不理解(譬如上面那种Pojo的书写方式,实质上是为了控制域的作用范围,增强域的访问安全性,所有的私有域都必须通过其自身的公共方法进行修改,也就是所谓的“对象自治”,这一点与Java中的思想是一致的,只是JS中是通过闭包来规范域的作用范围)。实质上只是因为他们仅仅是希望少写代码来完成更多的事,却没有考虑到这样的OO实现方式所带来的价值和意义。在这里也很庆幸现在自己有这么一位好老师能帮助我理清学习的路线,让我少走很多弯路,在此对老师表示感谢!
我老师的博客: arkliszeng    
                                                                                   By CodingMouse
                                                                                   2009年4月25日

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值