Jason ---分享,共同進步

          激情成就夢想,努力創造未來
          隨筆 - 53, 文章 - 1, 評論 - 45, 引用 - 0
          數據加載中……

          JavaScript面向對象編程

          一、引言
            長久以來,JavaScript在Web開發中一直處于被忽視的地位,甚至有相當一部分開發人員對它產生了誤解,認為JavaScript只不過是用來完成一些花哨功能的雕蟲小技。網絡上廣為流傳的低質量的JavaScript代碼對此也起到了推波助瀾的作用...很多應用中JavaScript都采用了面向過程的編程方式,代碼的可擴展性不好,復制粘貼的代碼比比皆是...
            隨著Ajax等技術的廣泛使用,YUI、Prototype等對JavaScript的應用可謂是淋漓盡致、出神入化。人們才發現原來JavaScript可以實現如此強大的功能,具備如此優雅的架構...

          二、準備
          1、概念
          JavaScript是一種弱類型語言。包括:
          基本類型:數字Number,字符串String,布爾值Boolean;
          復合類型:對象Object,數組Array;
          工具類型:全局對象Global,日期Date,數學對象Math,正則表達式RegExp,錯誤對象Error;
          特殊類型:函數Function。

          這里我只想說兩點:
          1)基本數據類型的包裝對象
          每一個基本數據類型都有一個對應的對象類。可以靈活地實現類型轉換。簡單地說,JavaScript不僅支持數字、字符串和布爾值這些數據類型,還支持Number、String、Boolean類,這些類是基本數據類型的包裝(wrapper)。
          例子:
          var s="some string";
          var len=s.length;
          這里,s保存了一個字符串,原始的字符串值是不會改變的。一個新的String對象被創建了,實現了對長度屬性的訪問,之后它就被銷毀了。
          其它例子:
          var a="some string";
          var b=new String("some string");
          var c=["a","b","c"];
          var d=new Array("a","b","c");

          alert(typeof a);//string
          alert(a instanceof String);//false
          alert(a instanceof Object);//false

          alert(typeof b);//object
          alert(b instanceof String);//true
          alert(b instanceof Object);//true

          alert(typeof c);//object
          alert(c instanceof Array);//true
          alert(c instanceof Object);//true

          alert(typeof d);//object
          alert(d instanceof Array);//true
          alert(d instanceof Object);//true

          2)Function類型
          做為JavaScript的一種特殊類型,我們將看到函數在面向對象編程中起到了非常關鍵的作用。

          2.值和引用
          類型 復制 傳遞 比較
          數字
          布爾值
          字符串 不可變的 不可變的
          對象 引用 引用 引用
          函數 引用 引用 引用
          數組 引用 引用 引用

          例子:
          var s1="hello";
          var s2="hell"+"o";
          alert(s1==s2);//true

          var d1=new Date();
          var d2=new Date();
          alert(d1==d2);//false

          3.this
          在構造函數中,指代新創建的對象實例;
          在對象的方法被調用時,指代調用該方法的對象實例。

          4.arguments
          arguments屬性由解釋器創建,用于訪問函數對象的每一個參數。

          5.callee,caller
          arguments的callee屬性獲取對正在執行的Function對象的引用;
          Function對象的caller屬性獲取正在調用當前函數的父函數對象。

          6.apply,call
          兩者都是將函數綁定到其它對象上執行的,區別在于調用方式:
          apply([thisObj[,argArray]])
          call([thisObj[,arg1[,arg2[,[,.argN]]]]])

          7.匿名函數
          (function(a,b){
           return a+b;
           })(1,1);
          等價于:
          function f(a,b){
           return a+b;
          }
          f(1,1);

          8.null,undefined
          null是JavaScript的關鍵字,表示空值。可以看作Object類型的一個特殊值。
          undefined不是關鍵字,它是一個全局變量,使用了未定義變量、變量未賦值、void運算符,都會返回“undefined”。

          9.constructor
          從JavaScript1.1開始,每個對象都具有一個constructor屬性,它引用的是用來初始化該對象的構造函數。

          10.prototype
          JavaScript1.1引入了原型對象的概念,每一個對象都有一個原型對象,對象可以繼承它的原型對象的所有屬性和方法。
          要為一個對象的類制定原型對象,需要將構造函數的prototype屬性設置為指定的對象。之后,如果用構造函數初始化對象時,會自動將指定的對象作為新創建對象的原型對象。

          注意:
          1)使用原型對象可以減少每個繼承對象的內存需求量;
          2)即使屬性是在對象被創建后才加到它的原型對象中的,對象也能夠繼承這些后定義的屬性。
          3)當調用一個對象的一個屬性時,先在該對象定義內查找該屬性,如果沒有該屬性才到該對象的原型對象中查找,依此類推。

          三、實現
          在面向對象編程中,我們可以把過程編程中的一個個function看作一個個獨立定義的類,函數名即為類名。
          1.例子:Circle類
          function Circle(radius){
           //實例變量
           this.r=radius;
          }

          //靜態變量
          Circle.PI=3.14159;

          //實例方法
          Circle.prototype.area=function(){
           return Circle.PI*this.r*this.r;
          }

          //靜態方法
          Circle.max=function(a,b){
           if(a.r>=b.r){
            return a;
           }
           else{
            return b;
           }
          }

          //調用
          var a=new Circle(2);
          var b=new Circle(3);
          var c=a.area();
          var d=Circle.max(a,b);

          2.繼承
          1)一種繼承方式
          //這里我們將CircleMore類的prototype指向了一個Circle類實例,
          //并增加了circumference方法。
          function CircleMore(radius){
           this.r=radius;
          }

          CircleMore.prototype=new Circle(0);

          CircleMore.prototype.circumference=function(){
           return 2*Circle.PI*this.r;
          }

          這樣能夠實現對Circle的繼承,但是這里存在一點問題:我們直接把CircleMore類的prototype指向了一個Circle類實例,這樣就覆蓋了JavaScript提供的原型對象,而且拋棄了給定的constructor屬性,這樣CircleMore的constructor屬性就指向了父類Circle的constructor屬性。而且這種方式總是使人感覺怪怪的。

          2)Ajax架構Prototype(區別前面提到的prototype哦)的繼承方式

          //Prototype框架為Object對象定義了extend方法,
          //將source的屬性和方法復制到了destination。
          Object.extend = function(destination, source) {
            for (var property in source)
              destination[property] = source[property];
            return destination;
          };

          //調用
          function ParentClass(){...}
          function SubClass(){}
          SubClass.prototype=Object.extend({
           newMethod:function(){
            alert("newMethod");
           }
          },
          ParentClass.prototype
          );

          3)如果這里對兩個參數交換位置,則是對原對象的開展。
          例子:通過extend方法對String對象進行了擴展

          Object.extend(String.prototype,{
           newMethod:function(){
            alert("newMethod");
           }
          });

          3.多態

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

          //基類
          function base(){}
          base.prototype={
           initialize:function(){
            this.oninit();//調用了一個虛方法
           }
          }

          //子類SubClassA
          function SubClassA(){}
          SubClassA.prototype=Object.extend({
           //...其它屬性方法
           prop:"SubClassA",
           oninit:function(){
            alert(this.prop);
           }},
           base.prototype
          }

          //子類SubClassB
          function SubClassB(){}
          SubClassB.prototype=Object.extend({
           //...其它屬性方法
           prop:"SubClassB",
           oninit:function(){
            alert(this.prop);
           }},
           base.prototype
          }

          //調用
          var a=new SubClassA();
          var b=new SubClassB();

          a.initialize();//輸出"SubClassA"
          b.initialize();//輸出"SubClassB"

          四、JavaScript與設計模式

          1.Singleton

          function Singleton(){
           if(Singleton.caller!=Singleton.getInstance){
            throw new Error("Can not new Singleton instance!");
           }
           this.prop="some string";
           //...
          }

          Singleton._instance=null;

          Singleton.getInstance=function(){
           if(this._instance==null){
            this._instance=new Singleton();
           }
           return this._instance;
          }

          var a=Singleton.getInstance();
          var b=Singleton.getInstance();
          b.prop="another string";
          alert(a.prop);//"another string"
          alert(b.prop);//"another string"

          2.Factory

          function XMLHttpFactory(){}

          XMLHttpFactory.createXMLHttp=function(){
           if(...){
            return new XMLHttpRequest();
           }
           else if(...){
            return new ActiveXObject("MSXML2.XMLHttp");
           }
           ...
          }

          var xmlhttp=XMLHttpFactory.createXMLHttp();

          五、備注

          參考資料:
          《JavaScript權威指南(第三版)》 中國電力出版社
          《JavaScript高級程序設計與應用實例》 人民郵電出版社
           Prototype 1.6.0
           YUI 2.3.1



          注:原文(http://www.cnblogs.com/charming/archive/2007/11/25/972110.html)
           

          posted on 2008-07-09 23:00 agun 閱讀(256) 評論(0)  編輯  收藏 所屬分類: 其他

          主站蜘蛛池模板: 宁晋县| 浮梁县| 宁夏| 内黄县| 金溪县| 嘉兴市| 历史| 丹东市| 长乐市| 东丰县| 合肥市| 德兴市| 万盛区| 石屏县| 罗江县| 无为县| 宁海县| 冀州市| 娱乐| 稻城县| 丰顺县| 宣武区| 石阡县| 古田县| 商南县| 鹤壁市| 布拖县| 密云县| 武夷山市| 六枝特区| 嘉定区| 定陶县| 屏边| 松原市| 天台县| 肇源县| 永修县| 新泰市| 临朐县| 铜山县| 邵武市|