無為

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

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

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


          <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(
          '執行方法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(
          '執行方法key:'?+?(o[key])())
          ?}
          ?
          }
          ?
          alert(o);
          alert(?
          new??Date());
          ?
          //?-->?
          ?</SCRIPT>?

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


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

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

          見如下代碼:

          <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返回的數據類型是和Object同等級的數據類型。它有Object實例(new Object())的一些特性,但它不是Object的實例,因為它沒有繼承Object.prototype.toString=function(){return 'myToString'};但我們Person.toString=function(){return 'Person toString'};改變了覆蓋了方法。
          在《javascript權威指南》中,作者用這個特性實現了“類方法、類變量”static方法,與java中不同,這些方法不能用new Person()來調用。

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

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

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

          <SCRIPT?LANGUAGE?=?"JavaScript">?
          <!--?
          ??
          var??Person?=?function??()??{
          ?????
          this?.name?=?'Person的構造函數中屬性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());?
          //?構造函數中的方法?
          ?alert(o);?//?訪問toString方法???先找??對象中?構造函數中???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就好了!');
          ?
          //?其實還是可以訪問到被覆蓋的原型的。那樣太復雜了。?
          //
          ?-->?
          </SCRIPT>?


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

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

          (1)對象屬性優先級
          通過運行以下代碼,我們訪問對象屬性優先級如下:c>b>d>e
          c種屬性必須在定義以后訪問才有效。a種屬性實例訪問不到。
          javascrpt語言預定義的屬性不能用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實例';
          }
          ?
          ?var??o?
          =?new??Person();
          ?
          for?(?var??key??in??o)??{
          ????alert(key?
          +?':'?+?o[key]);
          }
          ?
          //?-->?
          </?SCRIPT?>?

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

          <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的繼承是模擬實現的。和java,c++中是不同的。是依靠prototype實現的。
          我個人從來不用javascript的“繼承”,始終認為javascript實現的繼承不是真正的繼承。可能是受java”毒害“夠深。
          在javascript中,我把繼承分為兩類: 類繼承,對象繼承。
          (1)、prototype.js中的繼承
          prototype.js中用如下代碼實現繼承。我認為只是個屬性拷貝過程。

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

          //Object.prototype.extend 感覺這句話沒必要,太模仿java了,想讓對象實例直接繼承。
          ??? 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;
          ????}
          ?
          ????}
          ?);

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

          <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>?

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

          b、prototype.js中的對象繼承

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

          這個應用比較簡單,典型的對象之間屬性拷貝覆蓋。
          總結:關于prototype.js中繼承的實現,我們當成javascript對象的屬性拷貝可能在應用中更好理解。建議大家仔細讀讀prototype.js代碼可能體會更深。模仿prototype.js中extend的應用。感覺var Insertion = new Object(); 的實現比較經典。

          (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的繼承實現比較正統,也是《javascript權威指南》中的實現方法。注意最后一句代碼可以實現子類訪問父類原型對象的方法。

          <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一直沒時間仔細讀讀代碼。這部分詳細討論待續。
          (3)、總結
          關于javascript的繼承實現,建議一般不要使用,感覺很亂,代碼可讀性較差。一般也沒有使用必要。詳細在《9、javascript對象使用指南》中討論。


          javascript所有對象都繼承自Object類。以下是Object類的一些屬性。原型對象

          的一些屬性。

          1、constructor屬性
          從javascript1.1開始,每個對象都有這個屬性,它指向用來初始化改對象的構造

          函數

          ?

          <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的類型是函數;
          b、javascript內部實現了很多函數,如Object,Date都是函數由Function得到的


          c、用原型對象實現的繼承中,也要設置子類的constructor。如果你的程序中用

          到了constructor,可能會出錯。
          2、toString()方法
          相當于java Object類中toString方法。你alert()? + 等操作中就會調用這個方

          法。 var s='1'+'2',會自動把'1'? '2'? 轉化成String對象在執行。

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

          如果對象或子類要調用父類的方法可以

          ?

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

          ?

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

          什么用法。
          4、valueof()
          當javascript與要將一個對象轉化成字符串之外的原始類型時調用它。

          5、hasOwnProperty()方法
          《javascript權威指南》說如果是非繼承的屬性返回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(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權威指南》如果用能 for( in )枚舉的屬性,這個方法返回true;
          以下代碼說明《javascript權威指南》是錯的。自己定義的原型對象屬性可以枚

          舉,但返回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
          +='?是實例對象?';
          ?}
          else{
          ????????desc
          +='?不是實例對象?';
          ?}

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


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

          alert(desc);

          //-->
          </SCRIPT>



          7、isPrototypeOf方法
          《javascript權威指南》如果調用對象是實際參數指定的對象的原型對象返回

          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、總結
          看《javascript權威指南》前,就知道toString方法。現在知道了些其他的方法

          ,但讓我更加混亂,《javascript權威指南》講的也有錯誤。開發中建議大家除

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

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


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

          等。一般書上都叫對象層次和文檔對象模型。用dom標準來說,一般瀏覽器都實現

          了0級DOM,關于DOM標準我感覺知道0級就可以了。對于DOM標準W3C早已定義了1級

          ,2級,三級也在標準化,問題是各個瀏覽器不完全實現,尤其是IE的事件模型,

          完全不和DOM一致。(不過prototype.js已經做了很好的封裝)
          ??? 我這里不會講dom接口,更不會講各個瀏覽器的如何實現這些接口及區別。(

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

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

          2、引子

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

          以上簡單的javascript代碼,不知大家提出過疑問沒有。
          首先,document是個javascript對象,誰創建了它。;document的類是什么

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

          什么屬性或方法。這些對象與html關系是什么。這些對象與dom標準有什么關系。

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

          ,接口。

          3、一個簡單的例子的深入理解

          <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>

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

          一個屬性,也叫全局屬性。
          b、window,document在html最前面已經存在了。我們可以隨處使用document對象


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

          。當然我們編碼用到這些對象時,都在body.onload或鼠標觸發,一般不會出錯。
          d、例子中的document.getElementById('xm')javascript對象和我們自己創建的

          javascript對象有什么區別呢?從應用角度看沒有區別,只是自己定義的對象由

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

          象,我們直接用方法得到句柄就可以了(有多種方法)。
          e、我們怎么知道這些對象的用法呢?查看w3c DOM參考嗎?我認為不用。

          4、瀏覽器為我們創建的對象與我們自己定義的對象的區別。

          <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>

          希望你仔細的看看上面代碼的執行結果。可能你會得到更震撼的想法來。暫時我

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

          器的內建類。
          b、反過來,對于瀏覽器為我們創建的對象,我們可以當成自己的對象一樣使用。

          看看prototype.js中,使用了內建對象的方法。

          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屬性的值是什么,在網頁上表示什么。可以看出javascript對象的

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

          件的新思路,一個控件就是一個javascript對象(其實很多人都這樣做了,但好

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

          html標簽的UI控件無論性能、開發人員使用難度上都不錯。
          對于dojo的widget這種做UI做法我個人不很贊同,完全用div,圖片實現了一便

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

          是定死的,界面也比較單調,也不好修改。

          對于自己實現javascript控件,我認為在htmlUI基礎上就可以了,畢竟自己實現

          存在的UI難度不小。把html的標準UI組合成新的控件。例如,我們可以很容易的

          實現一個包括? (登陸 密碼 驗證碼 確認)? 的組合javascript控件


          d、dom標準與瀏覽器對象
          打開document.writeln(desc(document.getElementById('xm')));,你可以看到<

          input type="text">的所有屬性。這些屬性 ”dom標準“,之所以加引號,DOM標

          準我們有很多誤解,認為DOM標準是個什么高不可及、不可違抗的、復雜的東西。
          首先:我們接觸了靜態HTML,xml,有了DOM對象模型(熟悉java的都知道java的實

          現),但javascript語言的特點使不能象java,c++那樣來實現DOM對象模型。例如

          input 繼承了 HTMLElement,HTMLElement定義的一堆屬性。按照dom標準,所有瀏

          覽器實現 input javascript對象時都必須把這些屬性加上,這就叫符合標準。其

          實說白了:DOM標準就是瀏覽器為我們實現的javascript代碼的總和。(可以瀏覽

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

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

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

          還有用AJAX技術時
          'Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0', 其實很簡

          單,就是瀏覽器中有沒有這些javascript實現了。所有大家在DWR框架中用iframe

          實現了一個javascript? XMLHTTP類。

          e、與xhtml標準的矛盾
          在xhtml中,<input type="button"> 雙引號是必須的,但outerHTML屬性中卻沒

          雙引號。還沒想明白。

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

          Math,setTimeout())都可以由window對象訪問。另外瀏覽器的特殊函數或屬性。

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

          問我們可見的元素的入口(document.getElementById),也提供了動態創建html

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

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

          對象中去。

          6、對DOM標準的認識
          DOM標準定義了接口,沒有定義類。瀏覽器為我們實現了這些接口,實現這些接口

          的類我們也看不見。所以這里接口的含義和java中接口的含義不同。
          例如我們常用的document對象
          DOM標準中定義了個Document接口,實現HTMLElemnt接口。
          Document接口和HTMLElemnt接口在DOM標準中定義了很多屬性和方法。
          注意我們使用的document對象是瀏覽器為我們創建的javascript對象,到底

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

          人員來說只能當成一個參考手冊,象javadoc。

          7、如何寫出跨瀏覽器的javascript代碼
          ?? 這難度大了點.但說穿了,只要我們用javascript代碼把瀏覽器沒符合DOM標準

          的代碼補全就好了。但DOM標準之大不是一般人能全部搞清楚的,瀏覽器廠商也使

          壞,讓這個工作更難了。?? 現在好象有個誤區,人們寫javascript都喜歡按照

          DOM標準來寫。如果我們按照各個瀏覽器實現DOM標準的交集寫代碼的話,可能會

          更好點。




          凡是有該標志的文章,都是該blog博主Caoer(草兒)原創,凡是索引、收藏
          、轉載請注明來處和原文作者。非常感謝。

          posted on 2006-06-19 10:35 草兒 閱讀(443) 評論(0)  編輯  收藏 所屬分類: ajax
          主站蜘蛛池模板: 滕州市| 砚山县| 延吉市| 拉孜县| 定西市| 东方市| 南通市| 德钦县| 盘山县| 荥经县| 二手房| 和龙市| 闸北区| 定远县| 武平县| 上高县| 霍邱县| 博野县| 南木林县| 红河县| 仙桃市| 汕头市| 宁国市| 印江| 拉萨市| 蒲江县| 肇东市| 离岛区| 兖州市| 土默特右旗| 苗栗县| 临湘市| 彭阳县| 敖汉旗| 惠州市| 姚安县| 晋州市| 和林格尔县| 蒙阴县| 德兴市| 梅河口市|