DANCE WITH JAVA

开发出高质量的系统

常用链接

统计

积分与排名

好友之家

最新评论

面向对象(OOP)方法使用 JavaScript

private variables:原始的定义变量的方法 var
private functions:通过 var functionName=function(){}声明

privileged methods: 通过this.methodName=function(){}声明
privileged properties:通过 this.variableName来声明
(有些地方把privileged properties叫做public properties,但我感觉无论是按照
定义写法,还是为了便于理解都叫privileged properties更好些。更便于对比对称记忆)

prototype methods :通过Classname.prototype.methodname=function(){}来声明
(有些地方叫public method,同样和上边一样的理由,这里改叫prototype method)
prototype properties:通过 classname.prototype.propertyName=somevalue来声明

static properties: 通过classname.propertyName=somevalue定义
static method :通过classnamne.methodName来声明

说明:有些地方(例如我看的文档中)把privileged properties和prototype method叫成
public properties 和public method,不知道为什么这样叫。这样命名后造成的问题是
1,privileged method没有对应的privileged properties
2,prototype properties没有对应的prototype method
3,public method和public properties的定义方式又不对称

下边解释一下几种情况:
1,private:定义在类内部,只能被类内部的方法调用,例如privileged(见实例一中的(1)(2))
2,priviledged :定义在类内部,能被任何调用,在调用上有点类似Java中
的非静态public方法(见实例一中的(3))
3,prototype:这个概念不太好理解,在执行上有点像java的clone,只在类初始化的时候
执行一次。每次建立实例的时候不执行。能被继承。
4,static: 有点类似java中的静态。各实例共享,不能被继承
实例一如下:

<script>
        function Pet(name,color)
{
            
//priviledged properties
            this.name=name;
            
this.color=color;
            
//private properties
            var type="animal";
            
//private method
            var run2 = function(){
                run(type);
            }

            var run 
= function(mType){
                alert(color
+" "+name+" is runing("+mType+")");
            }

            
//priviledged method
            this.callRun = function(){
                
/*(1)priviledged method can visit private properties and private method*/
                run(type);
            }

        }


        Pet.prototype.callPrivateRun 
=function(pet){
        
/*(2)can not call run*/            
            
//pet.run2();
        /*(3)can call priviledge method and priviledge properties*/
            pet.callRun();
        }


        function test()
{
            var pet 
= new Pet("pig","black");
            pet.callRun();
            alert(
"prototype");
            pet.callPrivateRun(pet);

        }

        window.onload
=test;
    
</script>
继承与覆写
实例二演示了继承、覆写
另外javascript不支持多态性
<script>
        function Pet()
{
            
//name
            this.name=null;
            
this.getName = function() {return this.name;};
            
this.setName = function(newName) {this.name = newName;};
            
//abstract method
            this.eat = null;
        }

        
/*cat inherit from Pet*/
        Cat.prototype 
= new Pet();
        function Cat()
{
            
//implement the abstract method
            this.eat = function(food){
                alert(
"The cat (" + this.name+ ") is eating " + food);
            }

        }

        
/*dog inherit from Pet*/
        function Dog()
{
            
//implements the abstract method
            this.eat = function(food){
                alert(
"The dog (" + this.name+ ") is eating " + food);
            }

        }

        Dog.prototype 
= new Pet();
        
/*Hound inherit from dog*/
        Hound.prototype 
= new Dog()
        function Hound()
{
            
//override
            this.eat = function(food){
                alert(
"The Hound (" + this.name+ ") is eating " + food);
            }

        }


        function test()
{
            var cat 
= new Cat();
            cat.setName(
"mimi");
            cat.eat(
"fish");
            var dog 
= new Dog();
            dog.setName(
"wangwang");
            dog.eat(
"bone");
            var hound 
= new Hound();
            hound.setName(
"hali");
            hound.eat(
"rabbit");            
        }

        window.onload
=test;
    
</script>

posted on 2007-05-22 18:07 dreamstone 阅读(1849) 评论(3)  编辑  收藏 所属分类: 脚本语言javascript

评论

# re: 面向对象(OOP)方法使用 JavaScript 2007-05-22 23:50 热门单曲

多谢楼主分享 顶了  回复  更多评论   

# re: 面向对象(OOP)方法使用 JavaScript 2007-05-23 10:21 BeanSoft

不错, 收藏了!  回复  更多评论   

# re: 面向对象(OOP)方法使用 JavaScript[未登录] 2007-05-23 17:15 teddy

不错了,其实prototype是最好理解的。

在JavaScript中,如下:
function A() {
this.t1 = "ffffff";
this.t2 = function (msg) {
alert(msg);
};
};

A.prototype.p1 = "xxxx";

A.prototype.f1 = function () {
do something....
};

其实p1,f1是对function的prototype对象的操作,大家要明白,function
也是一个对象,对象也有属性,而prototype就是function的属性,该属性
也是一个对象,不同之处是,function在做为类定义的时候,创建类实例的
过程(new的过程)要参照它的prototype对象,把prototype对象的所有
属性(也就是Java里的成员,包括成员变量和成员函数)都复制到新的对象
中去,所以可以看出prototype就是模板,而这个模板是在new一个对象之
前就已经存在了。

上面的JavaScript就好像在定义一个Java类,不同的是JVM必须把类本身
载入虚拟机,然后才允许Java使用者new对象。而JavaScript,可以先建立
类(也就是定义function A的部分),然后再决定类中有什么成员(也就是
往A的prototype里追加成员部分)。

而在function A的函数体内定义的this成员,可以理解为‘后’绑定成员。
可以这么理解,在new A()的时候JavaScript建立了一个临时对象,
把A.prototype的所有成员复制到临时对象中,然后再把函数A中
定义的this成员也绑定到临时对象中,然后把临时对象返回给用户。
下面是模拟JavaScript的new关键字的处理伪过程:
//建立临时对象
var tobj = {};
//复制prototype
for (var key in A.prototype)
tobj[key] = A.prototype[key];
//绑定函数体内的this成员(这个过程没有办法模拟)
return tobj to user;

之所以存在function内部定义的this成员,以及prototype的成员是
有原因的。由于JavaScript的类在构造时是可以传递构造参数的,
所以,this成员的行为可能由于参数的不同而不同。这也就是需要后
绑定的原因了。在看下一个例子:
function AA(val1,val2) {
this.test1 = function() {
alert(val1);
};

this.test2 = val2 ? function () { return this.test1;} : function () { return 456; };

this.test3 = val1 ? val1 : function () {alert("no val1");};
}

这个例子很好的说明了后绑定的实际使用价值,所以后绑定对于成员
函数来说是非常有用的,对于成员变量来说其实没什么实际用处。
唯一不同的是,this成员在每次new对象时都要被JavaScript引擎解析,
原因很简单,根据不同的构造参数,使它们在运行期的行为可能有很大
的不同。而prototype的成员就不会每次都解析,第一次定义prototype
成员时才解析,以后可以直接引用prototype成员,并且更改了prototype
成员,所有已经建立的实例对象的相应成员都会被更改。

在运行期可以通过'对象名.成员名'来更改成员,这种方式可以更改this成员
和prototype成员的默认定义,但是更改只限于自身对象,因为JavaScript
和Java一样,也是传值,对象的引用也是一个地址值,所以new一个对象后,
prototype的成员也被复制到那个对象上了,再更改那个对象的成员,只会
影响那个对象自身,其他从同一个类new出来的对象都不会有任何变化。

不能通过运行期设置'类.prototype.成员名'来覆盖this同名成员,这样做没有
任何效果。

通过复制一个对象的所有属性到一个新对象,是不能通过修改prototype成员
来修改新对象的成员行为,因为新对象不是通过原来对象的类new出来的。
通常的复制方法如下:
var tobj = {};
for (var key in otherObj)
tobj[key] = otherObj[key];
看似tobj和otherObj的行为是一致的,他们不是一个类new出来的。

最后再谈谈prototype的constructor成员,该成员是对一个类的构造函数的引用,
在类定义的初期,如果一个类没有从其他别的类那里继承,该类的prototype.constructor属性保存的是该类自身的引用,如果该类从别的类
继承,那么它的constructor属性就保存了父类的constructor引用,
一般constructor没有什么用处,但可以通过它来取得他的类的信息,
就像Java里的对象都有getClass()方法,constructor就是干这个用的。
有它的好处是,再运行期可以改变所有同类对象的成员行为,如:
someObj.constructor.prototype.somePrototype = function () {
other process ....
}

因此好的习惯是在继承之后把prototype的constructor成员设置一下,
否则会把父类的prototype成员改掉,那样程序的行为就不可预知了。
如:
function classA() {

}

classB.prototype = new classA();
classB.prototype.constructor = classB;

至此所有和prototype有关的都介绍完毕,欢迎大家指正批评。

to 作者 : 本来我想少说两句,但是说了那么多,其实应该再开一篇
blog,但是我自己不写blog,只能在你这里写两句了,留着你自己再
整理以下吧。  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航: