無為

          無為則可為,無為則至深!

            BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
            190 Posts :: 291 Stories :: 258 Comments :: 0 Trackbacks

          1、對(duì)象的繼承
          在prototype.js中extend實(shí)現(xiàn)中,只是簡(jiǎn)單的屬性拷貝。
          在dojo 的lang.js中,也有個(gè)屬性拷貝的函數(shù) 叫 dojo.lang.mixin。顯然dojo的實(shí)現(xiàn)嚴(yán)謹(jǐn)多了。既沒有改變Object.prototype,另外toString函數(shù)也可以拷貝到目標(biāo)對(duì)象中。? 如果你熟悉 commons-beanutils 的copyProperties方法,那么就好理解了,但要注意javascript中function函數(shù)也是數(shù)據(jù)類型。

          ?

          dojo.lang.mixin? = ?function(obj,?props) {
          ?var?tobj?
          = ? {} ;
          ?
          for (var?x?in?props) {
          ??
          if (typeof?tobj[x]? == ? " undefined " ? || ?tobj[x]? != ?props[x])? {
          ???obj[x]?
          = ?props[x];
          ??}

          ?}

          ?
          // ?IE?doesn't?recognize?custom?toStrings?in?for..in
          ? if (dojo.render.html.ie? && ?dojo.lang.isFunction(props[ " toString " ])? && ?props[ " toString " ]? != ?obj[ " toString " ])? {
          ??obj.toString?
          = ?props.toString;
          ?}

          ?
          return ?obj;
          }

          ?

          例子代碼

          <SCRIPT LANGUAGE="JavaScript">
          <!--
          function pf(key,msg){
          ??? document.writeln("<div>"+key+':'+msg+"</div>");
          }
          Object.extend = function(destination, source) {
          ? for (property in source) {
          ??? destination[property] = source[property];
          ? }
          ? return destination;
          }
          function Source(name){
          ??? this.name=name;
          };
          Source.prototype.getName=function(){
          ??? return this.name;
          }
          Source.prototype.obj={name:'aaa'};
          Source.prototype.toString=function(){
          ??? return this.name;
          }
          var source=new Source('zkj');
          var obj={};
          pf('obj.name',obj.name)
          Object.extend(obj,source);
          pf('obj.name',obj.name)//zkj
          pf('source',source)//zkj
          pf('obj',obj)//沒有拷貝toString函數(shù)
          pf('source.obj.name',source.obj.name)//aaa
          obj.obj.name='bbb';
          pf('obj.obj.name',obj.obj.name) //bbb
          pf('source.obj.name',source.obj.name)
          //-->
          </SCRIPT>

          對(duì)象之間的屬性拷貝(extend) 和java c++中繼承概念完全不一樣。有幾個(gè)問題需要注意
          a、如果源對(duì)象的屬性在 (for in) 不出現(xiàn),那目標(biāo)對(duì)象將不全。? for in
          b、如果源對(duì)象的屬性是prototype的屬性,也可以拷貝,但目標(biāo)對(duì)象將當(dāng)作自己的屬性來使用。
          c、如果屬性是對(duì)象(引用傳遞),那任何持有者修改這個(gè)對(duì)象,內(nèi)容全部都修改了。所以只是“淺度clone”.你也可以模仿dwr? DWRUtil.toDescriptiveString方法實(shí)現(xiàn)多層的屬性拷貝(沒必要吧)。
          d、如果屬性是方法,那目標(biāo)對(duì)象使用方法可能會(huì)出現(xiàn)問題,因?yàn)榉椒ㄖ泻芸赡馨?this 關(guān)鍵字。所以我覺得javascript對(duì)象只當(dāng)作數(shù)據(jù)模型使用可能會(huì)簡(jiǎn)單很多。如DWR框架,這也是我喜歡dwr原因之一,完全以數(shù)據(jù)為核心的AJAX框架。

          2、自定義類的繼承
          我把用function定義的類叫自定義類。如 function Person(name){this.name=name}; 這種類有個(gè)復(fù)雜的原型對(duì)象porotype。
          如果用prototype.js實(shí)現(xiàn)這類的繼承,只能變相的通過原型對(duì)象的拷貝來實(shí)現(xiàn)。(Object.extend(des.prototype, source.prototype))。這樣兩個(gè)類的原型對(duì)象內(nèi)容一樣,但這種方法叫繼承太過牽強(qiáng),我感覺用起來有一定限制。(大家可以讀 prototype.js看到這種用法)

          關(guān)于類的繼承我推薦dojo或犀牛書中寫法。

          <SCRIPT LANGUAGE="JavaScript">
          var dojo={};
          dojo.lang={};
          dojo.inherits = function(subclass, superclass){
          ?subclass.prototype = new superclass();
          ?subclass.prototype.constructor = subclass;
          ?subclass.superclass = superclass.prototype;
          }
          dojo.lang.mixin = function(obj, props){
          ?var tobj = {};
          ?for(var x in props){
          ??if(typeof tobj[x] == "undefined" || tobj[x] != props[x]) {
          ???obj[x] = props[x];
          ??}
          ?}
          ?// IE doesn't recognize custom toStrings in for..in
          ?if(true) {
          ??obj.toString = props.toString;
          ?}
          ?return obj;
          }

          dojo.lang.extend = function(ctor, props){
          ?this.mixin(ctor.prototype, props);
          }

          dojo.lang.extendPrototype = function(obj, props){
          ?this.extend(obj.constructor, props);
          }
          function Person(){
          }
          Person.prototype.getName=function(){
          ??? return this.name;
          }
          Person.prototype.setName=function(name){
          ??? this.name=name;
          }
          Person.prototype.toString=function(){
          ??? return this.name;
          }
          function Man(){
          }
          dojo.inherits(Man, Person);
          dojo.lang.extend(Man,{
          getName:function(){return this.name+' of Man';},
          getAge:function(){return this.age;},
          setAge:function(age){this.age=age;}
          });
          var man=new Man();
          man.setName('zkj');
          man.setAge(25);
          alert(man.getName());
          alert(man.getAge());
          alert(Man.superclass.getName.call(man,null));//父方法
          </SCRIPT>


          這樣模擬的java中的繼承,也有方法覆蓋等概念,可對(duì)于javascript語言來說,這樣造成一定的復(fù)雜性。有幾個(gè)方面需要注意:
          a、在java中,繼承是為了代碼重用,語言的特性決定java繼承是有用的(多用接口代替繼承)。但javascript中,繼承存在好象沒那么必要,估計(jì)是那幫java迷的杰作。
          b、javascript語言的可重用代碼比較難寫,不同瀏覽器,語言版本也帶來一些復(fù)雜性。javascript包機(jī)制,模塊劃分,嚴(yán)格的語法檢查等等的不完善支持,造成javascript代碼的一片混亂。
          c、javascript在網(wǎng)頁中的作用與java,c++作用不同,實(shí)現(xiàn)的功能決定高級(jí)語言特征不需要。但現(xiàn)在ajax的興起可能有改觀。
          d、繼承雖然可以模擬實(shí)現(xiàn),但這只是模擬,并不是語言底層支持,在代碼質(zhì)量、代碼風(fēng)格、可讀性、可維護(hù)性都會(huì)造成一定麻煩。如果你用了dojo,那你必須讓讀你代碼的人也熟悉dojo。或知道你的代碼實(shí)現(xiàn)思路。
          e、IDE支持。javascrit極大的軟肋,就不多說。javascript框架的復(fù)雜度、推廣的難度,編譯檢查等,決定javascript的復(fù)雜應(yīng)用只是少數(shù)人能干的事。
          f、瀏覽器中javascript需要多線程嗎?好象csdn見有人模擬了個(gè)實(shí)現(xiàn)。完全不需要。瀏覽器下載了代碼,自己用自己的。所以我認(rèn)為 javascript中只有靜態(tài) (static)方法就夠了,沒必要有對(duì)象概念。只要var obj=new Object();這種只放數(shù)據(jù)的對(duì)象加上靜態(tài)方法就夠了。

          大家可以看看dojo的代碼。

          說這么多,在你自己寫的代碼中,你不要用javascript的類繼承,我寧愿ctrl+c\v 也不用繼承來重用代碼。除非dojo真的能統(tǒng)一江湖。

          參考:
          ?? <javascript權(quán)威指南>
          ???javascript的一些文章
          ?? prototype.js
          ?? dojo的文檔



          凡是有該標(biāo)志的文章,都是該blog博主Caoer(草兒)原創(chuàng),凡是索引、收藏
          、轉(zhuǎn)載請(qǐng)注明來處和原文作者。非常感謝。

          posted on 2006-06-19 10:24 草兒 閱讀(179) 評(píng)論(0)  編輯  收藏 所屬分類: ajax
          主站蜘蛛池模板: 梁山县| 灵武市| 宜宾市| 射洪县| 腾冲县| 新野县| 鞍山市| 大兴区| 望谟县| 法库县| 德庆县| 泊头市| 怀宁县| 镇康县| 山丹县| 兴安盟| 荥阳市| 阳山县| 蓝田县| 额敏县| 同江市| 南陵县| 星子县| 泗水县| 灌南县| 襄垣县| 张北县| 嘉峪关市| 合阳县| 宜都市| 合肥市| 阿拉善盟| 鄂伦春自治旗| 海兴县| 平南县| 玛曲县| 饶河县| 石阡县| 邮箱| 大同县| 启东市|