面向对象的Javascript和Prototype的理解
2011-11-19 10:08 AnyKoro 阅读(386) 评论(0) 编辑 收藏 举报JavaScript是一个函数式语言。在其中并没有class的概念。这个时候你可能会有疑问,没有class的概念又怎么实现面向对象的呢?
在JavaScript中式基于prototype的,中文意思是原型。在这里prototype更类似与c#或php中继承的作用。具体怎么理解看代码
这里我以php语言为比较对象
首先看JavaScript代码
//基函数,这里的原型不是prototype,只是基类的感觉
//这里使用namealias,是因为function自己有name属性,这里就是Foo
function Foo(){
this.namealias="Fooooo";
alert("constructor script");
this.doFoo=function(){
alert("doFoo");
}
}
//调用基函数中的方法,会提示Foo.doFoo不是一个函数
//Foo.doFoo();
//扩展基函数的方法
Foo.prototype.extendmethod=function()
{
alert("extend method");
}
//调用扩展方法
//此时如果使用Foo.extendmethod()方法调用的话,会找不到,
//这个很容易理解,基函数中是没有的,
//而在prototype中的只有在new的时候才会传给new出来的对象。
var fooObj=new Foo();
fooObj.extendmethod();//成功运行
fooObj.doFoo();//这里是可以运行基函数中的方法的。
Foo.prototype.constructor();
看了之后,你肯定你肯定会奇怪。其实只是没有搞清楚JavaScript中三个重要的角色,他们分别是
Object:对象,拥有且可以调用属性和方法。
Funtion:函数,拥有属性和方法,但不能调用,因为JavaScript认为Function是顺序执行的语句没有定义的部分。只有转为object才可以正确辨识。
Prototype:原型(实例),这个的概念,其实和Object有很大关系。Prototype外在表现不是一个Object,只是通过Prototype定义的东西,都会被new出来的Object访问到。因此,Prototype就常被用作扩展基函数(也可以认为是基类)的重要方法。但不是唯一,因为JavaScript本身也是支持对象动态增加属性和方法。只是Prototype在使用时,语意更明确,并且有具有construct()函数(Foo.prototype.construct();无需定义直接执行,代表执行基函数,基函数,其实也可以认为是中构造函数。)
但也一般情况只有Object可以调用prototype,函数只可以定义prototype,而无法调用。因为Object是没有prototype属性的,只有function有。但是对于function来说,他又看不到prototype中定义的东西,只有object可以。这么做的目的其实就是为了更好的语意!!当然万事皆有特殊,这里也有特殊。相信你前面就注意到了Foo.prototype.construct();,这里用的Foo,是Function。对的没有错,这个表示执行Foo中的函数的内容。这个construtor是在function中的prototype中可以看到的函数,同样也可以让Object看到(foo.constructor();)。这里关键要记住这个是个特例。
接下来附上一张图,能够很好,更清晰的理解上述所说
接下来我们来看看,相同功能和结构的PHP代码是如何实现的吧。
<?php
class Foo{
var $namealias;
function __construct()
{
$this->namealias="Fooooo";
echo "constructor script";
}
function doFoo()
{
echo "doFoo";
}
}
class subFoo extends Foo
{
function extendmethod()
{
echo "extend method";
}
}
$fooObj=new subFoo();
$fooObj->extendmethod();
$fooObj->doFoo();
比较两段,代码你可以更清楚的明白prototype的角色。
总结下,对于prototype你更可以理解成是对原有Function的一种类似子类的扩展,只是在js中没有子类这个东西,所以就是用prototype牵线搭桥,注意这里是牵线搭桥,也就是当你看不到prototype这根线时(也就是之前没有include过定义prototype的程序段)可就失效了。