無為

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

            BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
            190 Posts :: 291 Stories :: 258 Comments :: 0 Trackbacks
          a、基本數(shù)據(jù)類型的包裝對(duì)象。例如String Number Boolean.關(guān)于這三個(gè)包裝對(duì)象這里不準(zhǔn)備討論。建議直接用var s=""; var i=1; var b=false;定義,包裝類與java中的包裝類不同。javascript中不要用包裝類。
          ?? b、javascript預(yù)定義的對(duì)象。Function Array Date?? RegExp? Error等對(duì)象。這些對(duì)象使用比較簡(jiǎn)單,也不討論了。
          ?? c、用new Object()創(chuàng)建的對(duì)象。等同與var o={a:0,b:'s'};
          ?? d、用自定義的構(gòu)造函數(shù)創(chuàng)建的對(duì)象。function O(){};? var o=new O();
          ?? e、dom模型定義的構(gòu)造函數(shù),瀏覽器為你創(chuàng)建的對(duì)象。用var o=document.getElementById();或其他方法獲得。
          ?? f、null也是對(duì)象。typeof(null)= object.undefined我理解為變量預(yù)編譯的初始化值,而null是特殊的對(duì)象。如果一個(gè)變量=null,說明這個(gè)變量是個(gè)對(duì)象,但不是我上面提到的任何來源方式的對(duì)象。 如document.getElementById(頁面中不存在的id);可以產(chǎn)生一個(gè)null對(duì)象。

          ?? 用typeof()? 方法返回的是 object 的變量都是對(duì)象。 Function除外用new定義的不一定都是對(duì)象.


          <SCRIPT?LANGUAGE?=?"?JavaScript?">?
          <!--?
          Object.prototype.toString?
          =?function?()??{?return??'myToString'}?;
          ?var??o?
          =?new??Object();
          o.name?
          =?'zkj';
          o.age?
          =?25?;
          o.desc?
          =?function?()??{?return??'姓名:'?+?this?.name?+?',年齡:'?+?this?.age}?;
          ?
          for?(?var??key??in??o)??{
          ????alert(key?
          +?':'?+?o[key]?+?'?type:'?+?typeof?(o[key]))
          ??
          if?(?typeof?(o[key])?==?'?function?')??{
          ????????alert(
          '執(zhí)行方法key:'?+?(o[key])())
          ?}
          ?
          }
          ?
          alert(o);
          alert(?
          new??Date());
          ?
          //?-->?
          ?</SCRIPT>?????

          <SCRIPT?LANGUAGE?=?"JavaScript">?
          <!--?
          ?Object.prototype.toString?
          =?function?()??{?return??'myToString'}?;
          ?function??person()??
          {

          }
          ?
          ?var??o?
          =?new??person();
          o.name?
          =?'zkj';
          o.age?
          =?25?;
          o.desc?
          =?function?()??{?return??'姓名:'?+?this?.name?+?',年齡:'?+?this?.age}?;
          ?
          for?(?var??key??in??o)??{
          ????alert(key?
          +?':'?+?o[key]?+?'?type:'?+?typeof?(o[key]))
          ??
          if?(?typeof?(o[key])?==?'?function?')??{
          ????????alert(
          '執(zhí)行方法key:'?+?(o[key])())
          ?}
          ?
          }
          ?
          alert(o);
          alert(?
          new??Date());
          ?
          //?-->?
          ?</SCRIPT>?

          看以上兩段代碼,估計(jì)很多人對(duì)后面的代碼熟悉,也這樣寫了。可他們執(zhí)行結(jié)果是一樣的。如果你改變了javascript對(duì)象的原型對(duì)象后會(huì)有些區(qū)別。
          在這我想提出以下幾個(gè)問題:
          ??? a、javascript對(duì)象也是單根繼承的對(duì)象.但不是所有對(duì)象都繼承自O(shè)bject.如例子中的Date對(duì)象。
          ??? b、千萬別亂定義Object.prototype原型對(duì)象。prototype.js中加了個(gè)extends被人說了半天。但我們自己寫類庫時(shí),千萬別嘗試改Object的prototype。
          ??? c、別用javacript語言模仿java來寫代碼。想上面的,需要一個(gè)person的“類”,并不是非需要定義一個(gè),注意javascript對(duì)象的屬性是可以隨意增加或刪除的。并不象java那樣在類中寫死。
          ??? d、就上面兩段代碼有什么區(qū)別呢?可以簡(jiǎn)單的說是person繼承了Object”類“。javascript中對(duì)象的繼承是用prototype來實(shí)現(xiàn)的,后面我們討論prototype原型對(duì)象。
          ??? e、那我們應(yīng)用的時(shí)候到底是否該自己定義自己的構(gòu)造函數(shù)(如person),還是直接使用Object呢?這是個(gè)復(fù)雜的問題,我個(gè)人來說喜歡多用Object.


          開始之前我先明確個(gè)問題。如下代碼

          <SCRIPT?LANGUAGE?=?"JavaScript">?
          <!--?
          Person.type?
          =?"?person?"?;
          Person.writeType?
          =?function?()??{
          ????document.writeln(?
          this?.type);
          }
          ?
          ?
          //?var?Person?=?function(){}//如果這樣定義會(huì)報(bào)錯(cuò),可以看看前面文章,函數(shù)的預(yù)編譯。?
          ??function??Person()??{}?
          Person.writeType();
          alert(?typeof?(Person));
          ?
          for?(?var??key??in??Person)??{
          ????alert(key);
          }
          ?
          ?var??person?
          =?new??Person();
          //?-->?
          </SCRIPT>
          在這里Person是個(gè)函數(shù),但我們還可以定義它的屬性(type)。而Person有Object實(shí)例的特性(for in、可以定義屬性),但Person不是Object的實(shí)例。

          見如下代碼:

          <SCRIPT?LANGUAGE?=?"JavaScript">?
          <!--?
          Object.prototype.toString?
          =?function?()??{?return??'myToString'}?;
          ?function??Person()??
          {

          }
          ?
          ?Person.prototype.toString?
          =?function?()??{?return??'Person'}?;

          ?var??o?
          =?new??Person();
          alert(o);
          alert(Person)
          Person.toString?
          =?function?()??{?return??'Person?toString'}?;
          alert(Person)
          //?-->?
          </SCRIPT>?
          ?

          我理解function返回的數(shù)據(jù)類型是和Object同等級(jí)的數(shù)據(jù)類型。它有Object實(shí)例(new Object())的一些特性,但它不是Object的實(shí)例,因?yàn)樗鼪]有繼承Object.prototype.toString=function(){return 'myToString'};但我們Person.toString=function(){return 'Person toString'};改變了覆蓋了方法。
          在《javascript權(quán)威指南》中,作者用這個(gè)特性實(shí)現(xiàn)了“類方法、類變量”static方法,與java中不同,這些方法不能用new Person()來調(diào)用。

          Object?????????????????? function???????????? 同等級(jí) function可以定義屬性,可以(for in)

          new Object()??????? new function()??? 同等級(jí) new function()繼承了Object的prototype, ?????????????????????????????????????????????????????也會(huì)繼承 function的prototype

          小例子。看了原型對(duì)象就很清楚了啊。 原型對(duì)象最好在代碼最前面定義,很容易被覆蓋啊!

          <SCRIPT?LANGUAGE?=?"JavaScript">?
          <!--?
          ??
          var??Person?=?function??()??{
          ?????
          this?.name?=?'Person的構(gòu)造函數(shù)中屬性name';
          ?????
          this?.getName?=?function?()??{
          ??????????
          return???this?.name;
          ?}
          ?
          ??
          //?this.toString=function(){}??//你把注釋去掉看看效果?
          ?}
          ?
          Person.name?
          =?"?Person?"?;
          Person.toString?
          =?function?()??{?return???this?.name?+?'的類方法'}?;?//?我可以用this啊?
          ?alert(Person.toString())?//?類方法?
          ?var??o?=?new??Person();
          alert(o.getName());?
          //?構(gòu)造函數(shù)中的方法?
          ?alert(o);?//?訪問toString方法???先找??對(duì)象中?構(gòu)造函數(shù)中???Person的prototype中???????Object的prototype中?
          ??Object.prototype.toString?=?function?()??{?return??'Object的prototype中的toString'}?;
          alert(o);?
          //?Object的prototype中?
          ??Person.prototype.toString?=?function?()??{?return??'Person的prototpe中的toString'}?;
          alert(o);
          o.toString?
          =?function?()??{?return??'我覆蓋了toString方法了啊'}?
          alert(o);
          alert('我不能訪問前面的toString了。如果有super就好了!');
          ?
          //?其實(shí)還是可以訪問到被覆蓋的原型的。那樣太復(fù)雜了。?
          //
          ?-->?
          </SCRIPT>?


          原型對(duì)象prototype是Object或與之同等級(jí)的對(duì)象如(function,Number)的一個(gè)屬性,protorype是個(gè)對(duì)象。typeof的值是object。

          如果看了上一小節(jié)的最后一個(gè)例子,對(duì)自定義的“類”應(yīng)該比較熟悉了。
          在javascript中,可以說沒有方法,因?yàn)楹瘮?shù)和字符串一樣也是種數(shù)據(jù)類型,但類中的函數(shù)可以用this關(guān)鍵字。下面我說的類的屬性可以是方法,也可以指字段。
          在一個(gè)自定義“類”中有中有幾個(gè)地方可以定義屬性。
          ?? a、函數(shù)名中直接定義。? 如Person.name。在這定義相當(dāng)于類名的屬性。靜態(tài)的,訪問的時(shí)候必須用Person.name來訪問,不能用new Person().name訪問,也訪問不到。
          ?? b、構(gòu)造函數(shù)的this.中。當(dāng)你用new function()時(shí),這些屬性就是你所持對(duì)象的屬性。用new Person().屬性? 來訪問。
          ?? c、構(gòu)建好對(duì)象以后,給對(duì)象增加屬性。和構(gòu)造函數(shù)中的屬性使用類似。
          ?? d、函數(shù)名的prototype中
          ?? e、父類或Object 的prototype中。

          (1)對(duì)象屬性優(yōu)先級(jí)
          通過運(yùn)行以下代碼,我們?cè)L問對(duì)象屬性優(yōu)先級(jí)如下:c>b>d>e
          c種屬性必須在定義以后訪問才有效。a種屬性實(shí)例訪問不到。
          javascrpt語言預(yù)定義的屬性不能用for in 得到。如toString

          <SCRIPT?LANGUAGE?=?"JavaScript">?
          <!--?
          ?Object.prototype.toString?
          =?function?()??{}?;
          Object.prototype.name?
          =?"?Object?"?;
          Object.prototype.porotype_name?
          =?"?oObject?"?;
          Object.prototype.parent_name?
          =?"?pObject?"?;

          Person.prototype.name?
          =?"?Person?"?;
          Person.prototype.porotype_name?
          =?"?oPerson?"?;
          ?function??Person()??
          {
          ?????
          this?.name?=?'Person實(shí)例';
          }
          ?
          ?var??o?
          =?new??Person();
          ?
          for?(?var??key??in??o)??{
          ????alert(key?
          +?':'?+?o[key]);
          }
          ?
          //?-->?
          </?SCRIPT?>?

          (2)prototype屬性是只讀的
          看如下代碼,你不要試圖通過變量改變?cè)蛯?duì)象的屬性。你也不可能改變,你只會(huì)通過c模式給對(duì)象增加一個(gè)屬性。
          另外原型對(duì)象是所有實(shí)例共享的。理論上也不可以改變。

          <SCRIPT?LANGUAGE?="JavaScript">?
          <!--?
          Person.prototype.name?
          =?"?Person?"?;
          ?function??Person()??
          {
          ??
          }
          ?
          ?var??o?
          =?new??Person();
          ?var??o1?
          =?new??Person();
          alert(
          'o.name:'?+?o.name?+?'??'?+?'o1.name:'?+?o1.name);
          o.name?
          =?'zkj';
          alert(
          'o.name:'?+?o.name?+?'??'?+?'o1.name:'?+?o1.name);
          //?-->?
          </SCRIPT>?


          <SCRIPT?LANGUAGE?=?"JavaScript">?
          <!--?
          ?Object.extend??
          =???function?(destination,?source)???{
          ???
          for??(property??in??source)???{
          ????destination[property]??
          =??source[property];
          ??}
          ?
          ???
          return??destination;
          }
          ?
          ?
          ??function??Man()??
          {
          ?????
          this?.name?=?'zkj';
          }
          ?
          Man.prototype.type?
          =?'男人';
          Man.prototype.getType?
          =?function?()??{
          ?????
          return???this?.type;
          }
          ?
          ??function??Woman()??
          {}?
          ?
          Object.extend(Woman.prototype,Man.prototype);
          ?var??man?
          =?new??Man();
          ?var??woman?
          =?new??Woman();
          alert(man.getType());
          alert(man.name);
          alert(woman.getType());
          alert(woman.name);
          //?-->?
          </SCRIPT>?
          我只能說javascript的繼承是模擬實(shí)現(xiàn)的。和java,c++中是不同的。是依靠prototype實(shí)現(xiàn)的。
          我個(gè)人從來不用javascript的“繼承”,始終認(rèn)為javascript實(shí)現(xiàn)的繼承不是真正的繼承。可能是受java”毒害“夠深。
          在javascript中,我把繼承分為兩類: 類繼承,對(duì)象繼承。
          (1)、prototype.js中的繼承
          prototype.js中用如下代碼實(shí)現(xiàn)繼承。我認(rèn)為只是個(gè)屬性拷貝過程。

          Object.extend??=???function?(destination,?source)???{
          ???
          for??(property??in??source)???{
          ????destination[property]??
          =??source[property];
          ??}
          ?
          ???
          return??destination;
          }
          ?

          //Object.prototype.extend 感覺這句話沒必要,太模仿java了,想讓對(duì)象實(shí)例直接繼承。
          ??? a、prototype.js中的類繼承

          prototype.js??1.3?.?1?
          ?????String.prototype.extend(??
          {
          ??????stripTags:??function?()???
          {
          ???????
          return???this?.replace(?/<?\?/??[?^>?]?+>/?gi,?'');
          ????}
          ?,

          ????escapeHTML:??function?()???
          {
          ???????var??div??
          =??document.createElement('div');
          ???????var??text??
          =??document.createTextNode(?this?);
          ??????div.appendChild(text);
          ???????
          return??div.innerHTML;
          ????}
          ?,

          ????unescapeHTML:??function?()???
          {
          ???????var??div??
          =??document.createElement('div');
          ??????div.innerHTML??
          =???this?.stripTags();
          ???????
          return??div.childNodes[?0?].nodeValue;
          ????}
          ?
          ????}
          ?);

          ??? 我把這類型的繼承叫做類繼承,直接把你自己寫的對(duì)象屬性拷貝到原型對(duì)象中去。

          <SCRIPT?LANGUAGE?=?"JavaScript">?
          <!--?
          ?Object.extend??
          =???function?(destination,?source)???{
          ???
          for??(property??in??source)???{
          ????destination[property]??
          =??source[property];
          ??}
          ?
          ???
          return??destination;
          }
          ?
          ?
          ??function??Man()??
          {
          ?????
          this?.name?=?'zkj';
          }
          ?
          Man.prototype.type?
          =?'男人';
          Man.prototype.getType?
          =?function?()??{
          ?????
          return???this?.type;
          }
          ?
          ??function??Woman()??
          {}?
          ?
          Object.extend(Woman.prototype,Man.prototype);
          ?var??man?
          =?new??Man();
          ?var??woman?
          =?new??Woman();
          alert(man.getType());
          alert(man.name);
          alert(woman.getType());
          alert(woman.name);
          //?-->?
          </SCRIPT>?

          看了以上代碼,可能你會(huì)明白。直接拷貝類的原型對(duì)象確實(shí)可以實(shí)現(xiàn)某種概念上的繼承。
          但要注意:在繼承體系中,Man的原型對(duì)象屬性方法最好不要用Man的實(shí)例屬性(name),因?yàn)榭赡躓oman中并沒有定義實(shí)例屬性name;也最好不要用Man)原型對(duì)象屬性字段(type),雖然type也被拷貝過來了,但值還是”男人“。
          雖然有解決辦法,但javascript沒有很好的語法檢查工具,你用prototype.js的類繼承時(shí)小心處理。

          b、prototype.js中的對(duì)象繼承

          prototype.js 1.3.1
          this.options = {
          ????? method:?????? 'post',
          ????? asynchronous: true,
          ????? parameters:?? ''
          ??? }.extend(options || {});

          這個(gè)應(yīng)用比較簡(jiǎn)單,典型的對(duì)象之間屬性拷貝覆蓋。
          總結(jié):關(guān)于prototype.js中繼承的實(shí)現(xiàn),我們當(dāng)成javascript對(duì)象的屬性拷貝可能在應(yīng)用中更好理解。建議大家仔細(xì)讀讀prototype.js代碼可能體會(huì)更深。模仿prototype.js中extend的應(yīng)用。感覺var Insertion = new Object(); 的實(shí)現(xiàn)比較經(jīng)典。

          (2)、dojo-0.2.0-ajax中的繼承

          dojo.inherits??=???function?(subclass,?superclass)??{
          ??
          if?(?typeof??superclass??!=??'?function?')??{?
          ??dojo.raise(?
          "?superclass:??"?+?superclass?+?"??borken?"?);
          ?}
          ?
          ?subclass.prototype??
          =???new??superclass();
          ?subclass.prototype.constructor??
          =??subclass;
          ?subclass.superclass??
          =??superclass.prototype;
          ??
          //??DEPRICATED:?super?is?a?reserved?word,?use?'superclass'?
          ??subclass['super']??=??superclass.prototype;
          ?????}
          ?

          dojo的繼承實(shí)現(xiàn)比較正統(tǒng),也是《javascript權(quán)威指南》中的實(shí)現(xiàn)方法。注意最后一句代碼可以實(shí)現(xiàn)子類訪問父類原型對(duì)象的方法。

          <SCRIPT?LANGUAGE?=?"JavaScript">?
          ?
          <!--?
          ?
          ??function??Man()??
          {
          ?????
          this?.name?=?'zkj';
          }
          ?
          Man.prototype.type?
          =?'男人';
          Man.prototype.getType?
          =?function?()??{
          ?????
          return???this?.type;
          }
          ?
          ??function??Woman()??
          {}?
          ?
          Woman.prototype??
          =???new??Man();
          Woman.prototype.constructor??
          =??Woman;
          Woman.superclass??
          =??Man.prototype;
          ?
          //??DEPRICATED:?super?is?a?reserved?word,?use?'superclass'?
          ?Woman['super']??=??Man.prototype;
          Woman.prototype.type?
          =?'女人';

          ?var??man?
          =?new??Man();
          ?var??woman?
          =?new??Woman();
          alert(man.getType());
          alert(man.name);
          alert(woman.getType());
          alert(Woman.superclass.getType());
          alert(woman.name);

          //?-->?
          </SCRIPT>?

          看看代碼,感覺混亂。
          dojo一直沒時(shí)間仔細(xì)讀讀代碼。這部分詳細(xì)討論待續(xù)。
          (3)、總結(jié)
          關(guān)于javascript的繼承實(shí)現(xiàn),建議一般不要使用,感覺很亂,代碼可讀性較差。一般也沒有使用必要。詳細(xì)在《9、javascript對(duì)象使用指南》中討論。


          javascript所有對(duì)象都繼承自O(shè)bject類。以下是Object類的一些屬性。原型對(duì)象

          的一些屬性。

          1、constructor屬性
          從javascript1.1開始,每個(gè)對(duì)象都有這個(gè)屬性,它指向用來初始化改對(duì)象的構(gòu)造

          函數(shù)

          ?

          <SCRIPT?LANGUAGE="JavaScript">
          <!--
          function?Person(){}
          var?o=new?Person();

          alert(
          typeof(Person.constructor));
          alert(o.constructor);
          alert(Person.constructor);
          alert(Function.constructor);
          alert(Object.constructor)

          alert(
          new?Date().constructor);
          alert(Date.constructor);


          function?Man(){

          }

          Man.prototype
          =new?Person();
          alert(Man.constructor);
          o
          =new?Man();
          alert(o.constructor)
          Man.prototype.constructor
          =Man;
          alert(o.constructor)
          //-->
          </SCRIPT>

          ?

          如以上代碼,可以知道
          a、constructor的類型是函數(shù);
          b、javascript內(nèi)部實(shí)現(xiàn)了很多函數(shù),如Object,Date都是函數(shù)由Function得到的


          c、用原型對(duì)象實(shí)現(xiàn)的繼承中,也要設(shè)置子類的constructor。如果你的程序中用

          到了constructor,可能會(huì)出錯(cuò)。
          2、toString()方法
          相當(dāng)于java Object類中toString方法。你alert()? + 等操作中就會(huì)調(diào)用這個(gè)方

          法。 var s='1'+'2',會(huì)自動(dòng)把'1'? '2'? 轉(zhuǎn)化成String對(duì)象在執(zhí)行。

          但數(shù)組定義自己的toString方法。alert(Array.prototype.toString)

          如果對(duì)象或子類要調(diào)用父類的方法可以

          ?

          <SCRIPT?LANGUAGE="JavaScript">
          <!--
          alert([
          1,2,3].toLocalString())
          alert(Object.prototype.toString.apply([
          1,2,3]));
          //-->
          </SCRIPT>

          ?

          3、toLocalString()方法
          ECMAScript v3 javascript1.5中定義了這個(gè)方法。返回局部化的值。偶還不知道

          什么用法。
          4、valueof()
          當(dāng)javascript與要將一個(gè)對(duì)象轉(zhuǎn)化成字符串之外的原始類型時(shí)調(diào)用它。

          5、hasOwnProperty()方法
          《javascript權(quán)威指南》說如果是非繼承的屬性返回true.但下列代碼反映,它檢

          驗(yàn)對(duì)象的實(shí)例屬性。對(duì)原型屬性不會(huì)返回。

          ?

          <SCRIPT?LANGUAGE="JavaScript">
          <!--
          function?Person(name){
          ????
          this.name=name;
          }

          Person.prototype.setAge
          =function(age){
          ????
          this.age=age;
          }

          Person.prototype.toString
          =function(){
          ????
          return?'name:'+this.name+'?age:'+this.age;
          }

          var?o=new?Person('zkj');
          o.setAge(
          25);
          alert(o)
          alert(o.hasOwnProperty(
          "name"));
          alert(o.hasOwnProperty(
          "age"));
          alert(o.hasOwnProperty(
          "setAge"));
          alert(o.hasOwnProperty(
          "toString"));

          alert(Person.prototype.hasOwnProperty(
          "setAge"));
          //-->
          </SCRIPT>



          6、propertyIsEnumerable
          《javascript權(quán)威指南》如果用能 for( in )枚舉的屬性,這個(gè)方法返回true;
          以下代碼說明《javascript權(quán)威指南》是錯(cuò)的。自己定義的原型對(duì)象屬性可以枚

          舉,但返回false

          ?

          <SCRIPT?LANGUAGE="JavaScript">
          <!--
          function?Person(name){
          ????
          this.name=name;
          }

          Person.prototype.setAge
          =function(age){
          ????
          this.age=age;
          }

          Person.prototype.toString
          =function(){
          ????
          return?'name:'+this.name+'?age:'+this.age;
          }

          var?o=new?Person('zkj');
          o.setAge(
          25);
          alert(o.propertyIsEnumerable('setAge'));
          var?desc='';
          for(var?key?in?o){
          ????desc
          +=key+'??';
          ????
          if(o.hasOwnProperty(key)){
          ????????desc
          +='?是實(shí)例對(duì)象?';
          ?}
          else{
          ????????desc
          +='?不是實(shí)例對(duì)象?';
          ?}

          ?
          if(o.propertyIsEnumerable(key)){
          ????????desc
          +='?能被枚舉?';
          ?}
          else{
          ????????desc
          +='?不能被枚舉?';
          ?}


          ?desc
          +='\r\n';
          }

          alert(desc);

          //-->
          </SCRIPT>



          7、isPrototypeOf方法
          《javascript權(quán)威指南》如果調(diào)用對(duì)象是實(shí)際參數(shù)指定的對(duì)象的原型對(duì)象返回

          true. 看代碼吧。
          居然alert(Object.prototype.isPrototypeOf(Person));//true也是true.搞不懂

          ?

          <SCRIPT?LANGUAGE="JavaScript">
          <!--
          function?Person(name){
          ????
          this.name=name;
          }

          Person.prototype.setAge
          =function(age){
          ????
          this.age=age;
          }

          Person.prototype.toString
          =function(){
          ????
          return?'name:'+this.name+'?age:'+this.age;
          }

          var?o=new?Person('zkj');
          o.setAge(
          25);
          alert(Person.prototype.isPrototypeOf(o));
          //true
          alert(Person.isPrototypeOf(o));//false
          alert(o.isPrototypeOf(Person.prototype));//false
          alert(Function.prototype.isPrototypeOf(Person));//true
          alert(Object.prototype.isPrototypeOf(Person));//true
          //
          -->
          </SCRIPT>


          ?

          8、總結(jié)
          看《javascript權(quán)威指南》前,就知道toString方法。現(xiàn)在知道了些其他的方法

          ,但讓我更加混亂,《javascript權(quán)威指南》講的也有錯(cuò)誤。開發(fā)中建議大家除

          了toString,其他屬性方法不要覆蓋也不要使用了。除了對(duì)這些方法十分清楚。就

          我知道的javascript開源框架中好象沒用到這些。


          1、廢話
          ?? 這部分將要描述瀏覽器為我們創(chuàng)建的對(duì)象。就是大家熟悉的window,document

          等。一般書上都叫對(duì)象層次和文檔對(duì)象模型。用dom標(biāo)準(zhǔn)來說,一般瀏覽器都實(shí)現(xiàn)

          了0級(jí)DOM,關(guān)于DOM標(biāo)準(zhǔn)我感覺知道0級(jí)就可以了。對(duì)于DOM標(biāo)準(zhǔn)W3C早已定義了1級(jí)

          ,2級(jí),三級(jí)也在標(biāo)準(zhǔn)化,問題是各個(gè)瀏覽器不完全實(shí)現(xiàn),尤其是IE的事件模型,

          完全不和DOM一致。(不過prototype.js已經(jīng)做了很好的封裝)
          ??? 我這里不會(huì)講dom接口,更不會(huì)講各個(gè)瀏覽器的如何實(shí)現(xiàn)這些接口及區(qū)別。(

          我也沒這能力)。而是要猜測(cè)一下瀏覽器是怎么用javascript定義這些接口或類

          的。(注意是猜測(cè),個(gè)人理解)

          2、引子

          <SCRIPT LANGUAGE="JavaScript">
          <!--
          alert(document);
          alert(typeof(document));
          //alert(Document);//出錯(cuò)
          function desc(obj){
          ? var ret='';
          ? for(var key in obj){
          ??? ret+=key+':'+obj[key]+'</br>';
          ? }
          ? return ret;
          }
          document.writeln(desc(document));
          //-->
          </SCRIPT>

          以上簡(jiǎn)單的javascript代碼,不知大家提出過疑問沒有。
          首先,document是個(gè)javascript對(duì)象,誰創(chuàng)建了它。;document的類是什么

          (function Document(){....} 可能是new Document()創(chuàng)建了它);document有些

          什么屬性或方法。這些對(duì)象與html關(guān)系是什么。這些對(duì)象與dom標(biāo)準(zhǔn)有什么關(guān)系。

          接下來將試著回答這些問題。我會(huì)側(cè)重講述我的理解思路,而不是具體哪個(gè)方法

          ,接口。

          3、一個(gè)簡(jiǎn)單的例子的深入理解

          <SCRIPT LANGUAGE="JavaScript">
          <!--
          ??? alert(document);//存在
          ??? alert(this.document==window.document);//true
          //-->
          </SCRIPT>
          <HTML>
          <HEAD>
          <TITLE> New Document </TITLE>
          <SCRIPT LANGUAGE="JavaScript">
          ??? alert(document.getElementById('xm'));//null
          </SCRIPT>
          </HEAD>
          <SCRIPT LANGUAGE="JavaScript">
          ??? alert(document.getElementById('xm'));//null
          </SCRIPT>
          <BODY>
          <SCRIPT LANGUAGE="JavaScript">
          ??? alert(document.getElementById('xm'));//null
          </SCRIPT>
          <input type="text" id="xm">
          <SCRIPT LANGUAGE="JavaScript">
          ??? alert(document.getElementById('xm'));//存在
          </SCRIPT>
          </BODY>
          <SCRIPT LANGUAGE="JavaScript">
          ??? alert(document.getElementById('xm'));//存在
          </SCRIPT>
          </HTML>

          上面代碼說明幾個(gè)問題:
          a、window\this就是我在變量篇里面提到過的窗體的全局對(duì)象,document是它的

          一個(gè)屬性,也叫全局屬性。
          b、window,document在html最前面已經(jīng)存在了。我們可以隨處使用document對(duì)象


          c、對(duì)于輸入框按鈕這類html標(biāo)記的javascript對(duì)象只有在解釋過以后才能訪問到

          。當(dāng)然我們編碼用到這些對(duì)象時(shí),都在body.onload或鼠標(biāo)觸發(fā),一般不會(huì)出錯(cuò)。
          d、例子中的document.getElementById('xm')javascript對(duì)象和我們自己創(chuàng)建的

          javascript對(duì)象有什么區(qū)別呢?從應(yīng)用角度看沒有區(qū)別,只是自己定義的對(duì)象由

          自己new來初始化,而document.getElementById('xm')有瀏覽器為我們初始化對(duì)

          象,我們直接用方法得到句柄就可以了(有多種方法)。
          e、我們?cè)趺粗肋@些對(duì)象的用法呢?查看w3c DOM參考嗎?我認(rèn)為不用。

          4、瀏覽器為我們創(chuàng)建的對(duì)象與我們自己定義的對(duì)象的區(qū)別。

          <input type="text" id="xm" value="aaa">
          <INPUT TYPE="button" value='click me' onclick="alert

          (document.getElementById('xm').value);
          alert(document.getElementById('myxm').value);">
          <br>
          <SCRIPT LANGUAGE="JavaScript">
          <!--
          function desc(obj){
          ? var ret='';
          ? for(var key in obj){
          ??? ret+=key+':'+obj[key]+'</br>';
          ? }
          ? return ret;
          }
          function MyText(id,value){
          ??? this.id=id;
          ?this.outHtml='<input type=text id='+id+' value='+value+'>';
          ?this.toString=function(){
          ??????? return this.outHtml;
          ?}
          ?//...
          ?//...
          ?//...
          }
          //document.writeln(desc(document.getElementById('xm')));
          var myText=new MyText('myxm','zkj');
          document.writeln(myText);
          //-->
          </SCRIPT>

          希望你仔細(xì)的看看上面代碼的執(zhí)行結(jié)果。可能你會(huì)得到更震撼的想法來。暫時(shí)我

          有以下幾個(gè)感想:
          a、我們自己也可以寫一個(gè)界面控件,如果把屬性建立全的話,完全可以復(fù)原瀏覽

          器的內(nèi)建類。
          b、反過來,對(duì)于瀏覽器為我們創(chuàng)建的對(duì)象,我們可以當(dāng)成自己的對(duì)象一樣使用。

          看看prototype.js中,使用了內(nèi)建對(duì)象的方法。

          escapeHTML: function() {
          ??? var div = document.createElement('div');
          ??? var text = document.createTextNode(this);
          ??? div.appendChild(text);
          ??? return div.innerHTML;
          ? },
          ? unescapeHTML: function() {
          ??? var div = document.createElement('div');
          ??? div.innerHTML = this.stripTags();
          ??? return div.childNodes[0] ? div.childNodes[0].nodeValue : '';
          ? },
          c、大家可以打開描述注釋,看看<input >到底包含哪些屬性和方法。注意

          outerHTML屬性的值是什么,在網(wǎng)頁上表示什么。可以看出javascript對(duì)象的

          outerHTML屬性就是html(xhtml)規(guī)范中的標(biāo)簽。這樣給了我們寫javascriptUI控

          件的新思路,一個(gè)控件就是一個(gè)javascript對(duì)象(其實(shí)很多人都這樣做了,但好

          象都是innerHtml等等)。可以象asp.net或jsf那樣編寫組合控件。
          大家可以看一下ActiveWidgets代碼(與我的思路有些差別),我認(rèn)為這種基于

          html標(biāo)簽的UI控件無論性能、開發(fā)人員使用難度上都不錯(cuò)。
          對(duì)于dojo的widget這種做UI做法我個(gè)人不很贊同,完全用div,圖片實(shí)現(xiàn)了一便

          html的UI標(biāo)簽。性能不好,開發(fā)人員上手不容易,美工更不能修改,另外圖片都

          是定死的,界面也比較單調(diào),也不好修改。

          對(duì)于自己實(shí)現(xiàn)javascript控件,我認(rèn)為在htmlUI基礎(chǔ)上就可以了,畢竟自己實(shí)現(xiàn)

          存在的UI難度不小。把html的標(biāo)準(zhǔn)UI組合成新的控件。例如,我們可以很容易的

          實(shí)現(xiàn)一個(gè)包括? (登陸 密碼 驗(yàn)證碼 確認(rèn))? 的組合javascript控件


          d、dom標(biāo)準(zhǔn)與瀏覽器對(duì)象
          打開document.writeln(desc(document.getElementById('xm')));,你可以看到<

          input type="text">的所有屬性。這些屬性 ”dom標(biāo)準(zhǔn)“,之所以加引號(hào),DOM標(biāo)

          準(zhǔn)我們有很多誤解,認(rèn)為DOM標(biāo)準(zhǔn)是個(gè)什么高不可及、不可違抗的、復(fù)雜的東西。
          首先:我們接觸了靜態(tài)HTML,xml,有了DOM對(duì)象模型(熟悉java的都知道java的實(shí)

          現(xiàn)),但javascript語言的特點(diǎn)使不能象java,c++那樣來實(shí)現(xiàn)DOM對(duì)象模型。例如

          input 繼承了 HTMLElement,HTMLElement定義的一堆屬性。按照dom標(biāo)準(zhǔn),所有瀏

          覽器實(shí)現(xiàn) input javascript對(duì)象時(shí)都必須把這些屬性加上,這就叫符合標(biāo)準(zhǔn)。其

          實(shí)說白了:DOM標(biāo)準(zhǔn)就是瀏覽器為我們實(shí)現(xiàn)的javascript代碼的總和。(可以瀏覽

          器廠商不完全實(shí)現(xiàn))
          看protorype.js的代碼
          為了支持多了瀏覽器,定義下面代碼。說明有的瀏覽器網(wǎng)頁全局變量里有Element

          ,Event,有些瀏覽器沒給我們定義。所以只能這樣了。

          if (!window.Element) {
          ? var Element = new Object();
          }
          if (!window.Event) {
          ? var Event = new Object();
          }

          還有用AJAX技術(shù)時(shí)
          'Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0', 其實(shí)很簡(jiǎn)

          單,就是瀏覽器中有沒有這些javascript實(shí)現(xiàn)了。所有大家在DWR框架中用iframe

          實(shí)現(xiàn)了一個(gè)javascript? XMLHTTP類。

          e、與xhtml標(biāo)準(zhǔn)的矛盾
          在xhtml中,<input type="button"> 雙引號(hào)是必須的,但outerHTML屬性中卻沒

          雙引號(hào)。還沒想明白。

          5、瀏覽器為我們創(chuàng)建了幾類對(duì)象
          a、全局對(duì)象window或this。其實(shí)javascript的全局變量、全局方法(如

          Math,setTimeout())都可以由window對(duì)象訪問。另外瀏覽器的特殊函數(shù)或?qū)傩浴?/p>

          (如window.status,window.alert())
          b、document對(duì)象。包括圖片,applet,form等屬性,可能我們用的最多。也是訪

          問我們可見的元素的入口(document.getElementById),也提供了動(dòng)態(tài)創(chuàng)建html

          標(biāo)簽的方法。如var t=new Text("test");沒有這樣方法,只能 var

          t=document.creatTextNode("test");都由document提供的工廠方法來創(chuàng)建。
          c、頁面中的html標(biāo)簽,當(dāng)解釋執(zhí)行過,瀏覽器會(huì)為你初始化對(duì)象,放到document

          對(duì)象中去。

          6、對(duì)DOM標(biāo)準(zhǔn)的認(rèn)識(shí)
          DOM標(biāo)準(zhǔn)定義了接口,沒有定義類。瀏覽器為我們實(shí)現(xiàn)了這些接口,實(shí)現(xiàn)這些接口

          的類我們也看不見。所以這里接口的含義和java中接口的含義不同。
          例如我們常用的document對(duì)象
          DOM標(biāo)準(zhǔn)中定義了個(gè)Document接口,實(shí)現(xiàn)HTMLElemnt接口。
          Document接口和HTMLElemnt接口在DOM標(biāo)準(zhǔn)中定義了很多屬性和方法。
          注意我們使用的document對(duì)象是瀏覽器為我們創(chuàng)建的javascript對(duì)象,到底

          document對(duì)象有哪些屬性和方法是有瀏覽器決定的,而不是由DOM標(biāo)準(zhǔn)決定的。
          在這里javascript世界里沒有繼承概念,所以DOM標(biāo)準(zhǔn)定義的接口,對(duì)于我們開發(fā)

          人員來說只能當(dāng)成一個(gè)參考手冊(cè),象javadoc。

          7、如何寫出跨瀏覽器的javascript代碼
          ?? 這難度大了點(diǎn).但說穿了,只要我們用javascript代碼把瀏覽器沒符合DOM標(biāo)準(zhǔn)

          的代碼補(bǔ)全就好了。但DOM標(biāo)準(zhǔn)之大不是一般人能全部搞清楚的,瀏覽器廠商也使

          壞,讓這個(gè)工作更難了。?? 現(xiàn)在好象有個(gè)誤區(qū),人們寫javascript都喜歡按照

          DOM標(biāo)準(zhǔn)來寫。如果我們按照各個(gè)瀏覽器實(shí)現(xiàn)DOM標(biāo)準(zhǔn)的交集寫代碼的話,可能會(huì)

          更好點(diǎn)。




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

          posted on 2006-06-19 10:35 草兒 閱讀(443) 評(píng)論(0)  編輯  收藏 所屬分類: ajax
          主站蜘蛛池模板: 阜新市| 玛纳斯县| 兴隆县| 定安县| 桑植县| 迭部县| 合肥市| 镇平县| 宁波市| 岐山县| 吴忠市| 营口市| 临猗县| 灌云县| 玉山县| 彭泽县| 锡林浩特市| 内乡县| 广丰县| 牙克石市| 罗田县| 辽阳市| 福海县| 西林县| 双流县| 东城区| 青海省| 吴旗县| 沁阳市| 包头市| 潜江市| 财经| 抚州市| 久治县| 巴彦县| 鲁甸县| 宣武区| 乌兰浩特市| 隆安县| 卫辉市| 长沙县|