谁动了我的代码

抽象即是空,空即是抽象。
posts(43) comments(24) trackbacks(0)
  • BlogJava
  • 联系
  • RSS 2.0 Feed 聚合
  • 管理

News

所有文章版权归我所有,转载请注明出处,谢谢!

常用链接

  • 我的随笔
  • 我的评论
  • 我的参与
  • 最新评论

留言簿

  • 给我留言
  • 查看公开留言
  • 查看私人留言

随笔分类

  • Android开发(5)
  • C/C++(1)
  • DataBase(3)
  • Java(16)
  • JavaScript(14)
  • WEB前端(1)
  • 编程杂项(2)
  • 网络(1)

随笔档案

  • 2016年5月 (1)
  • 2011年2月 (1)
  • 2010年6月 (3)
  • 2010年5月 (1)
  • 2009年12月 (2)
  • 2009年11月 (1)
  • 2009年10月 (2)
  • 2009年6月 (2)
  • 2009年5月 (1)
  • 2009年4月 (2)
  • 2009年3月 (4)
  • 2009年2月 (1)
  • 2009年1月 (1)
  • 2008年12月 (1)
  • 2008年11月 (1)
  • 2008年10月 (4)
  • 2008年9月 (2)
  • 2008年5月 (5)
  • 2008年3月 (3)
  • 2007年12月 (2)
  • 2007年10月 (1)
  • 2007年9月 (2)
  • 2007年5月 (1)

搜索

  •  

最新评论

  • 1. re: Android之ImageView载入网络上的图片
  • 222222222222222222222
  • --2222222222222222222222222222
  • 2. re: Log4j自带Log Viewer的用法
  • 执行你的根本不行,乱错帖子就在这乱贴,tmd
  • --asdf
  • 3. re: Android之使用私有存储
  • getDir方法创建的文件,会有个app_前缀,请问这怎么去掉呢?
  • --就是宝宝
  • 4. re: Android通用事件造成的生命周期变化情况
  • 我相信以后Android将成为越来越多设备的OS,不光是手持上网设置,冰箱、洗衣机都有可能采用Android。
  • --淘宝网女装春装新款
  • 5. re: Android通用事件造成的生命周期变化情况
  • 不错
  • --歌瑞尔内衣

阅读排行榜

评论排行榜

View Post

关于JavaScript的Prototype更进一步的讨论

本文里讲述的是关于JavaScript的prototype问题,至于具体的JavaScript面向对象的编程教程,请各位看客到其他网站搜索一下,或者到这里看看。

首先开始一个例子,如下:

 1 function A() { 
 2     this.t1 = "ffffff"; 
 3     this.t2 = function (msg) { 
 4         alert(msg); 
 5     }; 
 6 }; 
 7 
 8 A.prototype.p1 = "xxxx"; 
 9 
10 A.prototype.f1 = function () { 
11      do something. 
12 }; 

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

上面的JavaScript就好像在定义一个Java类,书写类的时候,除了用不同的声明
(Class和Function)区别,基本没有其他的区别,但在运行时有很大的区别。
首先Java要求类必须被编译成字节码才能被载入虚拟机,而JavaScript是在运行
代码的同时,执行了类似Java的编译载入的过程。并且Java的类在载入虚拟机
后一般就不能再改变类的定义了,比如把一个方法的行为改变或指向另一个方
法的引用等。而JavaScript在运行期还可以通过prototype来改变类及所有该类生成
的对象的行为。例如上面的例子中,在解析完function A的函数体后,整个类也
就生成了,这时候如果new的话就能得到类的实例,紧接着的代码又向类动态
添加了新的行为。

而在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成员(这个过程是JavaScript的内部处理,没有办法模拟)
return tobj to user;

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

1 function AA(val1,val2) { 
2     this.test1 = function() { 
3         alert(val1); 
4     }; 
5 
6     this.test2 = val2 ? function () { return this.test1;} : function () { return 456; }; 
7 
8     this.test3 = val1 ? val1 : function () {alert("no val1");}; 
9 } 

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

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

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

通过复制一个对象的所有属性到一个新对象,是不能通过修改prototype成员
来修改新对象的成员行为,因为新对象不是通过原来对象的类new出来的。
通常的复制方法如下:

1 var tobj = {}; 
2 for (var key in otherObj) 
3     tobj[key] = otherObj[key]; 

看似tobj和otherObj的行为是一致的,他们不是一个类new出来的。
一个很好的办法可以测试,比如otherObj是A类new出来的,
可以通过使用 (tobj instanceof A) 来测试,结果显然是false。

最新的测试表明,这种复制方法可以复制所有自定义方法,
但是系统提供的默认方法是不能被复制的,即使你显式的覆盖了
系统默认提供的方法,如toString方法等。

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

1 someObj.constructor.prototype.somePrototype = function () { 
2 other process . 
3 } 

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

1 function classA() { 
2 
3 } 
4 
5 classB.prototype = new classA(); 
6 classB.prototype.constructor = classB; 
7 

我要说的关于JavaScript的prototype属性就这么多,大家多提意见多交流。
有错误的地方请大家指正。
还有第一次写blog,排版很糟糕,大家将就着看吧,以后会慢慢提高的,呵呵。

posted on 2007-05-26 08:49 Eric Song 阅读(1113) 评论(1)  编辑  收藏 所属分类: JavaScript

View Comments

# re: 关于JavaScript的Prototype更进一步的讨论  回复  更多评论   
继续加油,呵呵。
以后会常来逛游学习
2007-05-27 17:24 | dreamstone
新用户注册  刷新评论列表  

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


网站导航:
博客园   IT新闻   Chat2DB   C++博客   博问   管理
相关文章:
  • 关于样式表对象style与currentStyle的区别
  • 关于JavaScript的cloneNode方法对于节点上的事件clone问题的研究。
  • 参考Prototype的Class.create写了一个类似的实现,但是不是Ruby like OOP,使用上更像Java。
  • 对JavaScript的变量作用域的理解
  • IE document compatMode
  • JavaScript对form及form中的引用。
  • JavaScript注意事项(不定期更新)
  • 在定义一个js类的时候,为什么要设置该类的prototype属性为它所要继承的类的实例对象
  • JavaScript 类型转换注意事项
  • 面向对象的JavaScript(二,TSS上的一篇文章,先借鉴一下)
 
 
Powered by:
BlogJava
Copyright © Eric Song