<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    JAVA & XML & JAVASCRIPT & AJAX & CSS

    Web 2.0 技術儲備............

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      77 隨筆 :: 17 文章 :: 116 評論 :: 0 Trackbacks

    轉自 : http://www.bjcan.com/hengxing/readlou.asp?id=1162

    八、JavaScript面向對象的支持
    ~~~~~~~~~~~~~~~~~~
    很少有人對JavaScript的面向對象特性進行系統的分析。我希望接下來的文字讓你了解到這
    個語言最少為人知的一面。


    1. JavaScript中的類型
    --------
    雖然JavaScript是一個基于對象的語言,但對象(Object)在JavaScript中不是第一型的。JS
    是以函數(Function)為第一型的語言。這樣說,不但是因為JS中的函數具有高級語言中的函
    數的各種特性,而且也因為在JS中,Object也是由函數來實現的。——關于這一點,可以在
    后文中“構造與析構”部分看到更進一步的說明。

    JS中是弱類型的,他的內置類型簡單而且清晰:
    ---------------------------------------------------------
    undefined : 未定義
    number??? : 數字
    boolean?? : 布爾值
    string??? : 字符串
    function? : 函數
    object??? : 對象

    ?1). undefined類型
    ========================
    在IE5及以下版本中,除了直接賦值和typeof()之外,其它任何對undefined的操作都將導致
    異常。如果需要知道一個變量是否是undefined,只能采用typeof()的方法:
    <script>
    var v;
    if (typeof(v) == 'undefined') {
    ? // ...
    }
    </script>

    但是在IE5.5及以上版本中,undefined是一個已實現的系統保留字。因此可以用undefined來
    比較和運算。檢測一個值是否是undefined的更簡單方法可以是:
    <script>
    var v;
    if (v === undefined) {
    ? // ...
    }
    </script>

    因此為了使得核心代碼能(部分地)兼容IE5及早期版本,Romo核心單元中有一行代碼用來
    “聲明”一個undefined值:
    //---------------------------------------------------------
    // code from Qomolangma, in JSEnhance.js
    //---------------------------------------------------------
    var undefined = void null;

    這一行代碼還有一點是需要說明的,就是void語句的應用。void表明“執行其后的語句,且
    忽略返回值”。因此在void之后可以出現能被執行的任何“單個”語句。而執行的結果就是
    undefined。當然,如果你愿意,你也可以用下面的代碼之一“定義undefined”。
    //---------------------------------------------------------
    // 1. 較復雜的方法,利用一個匿名的空函數執行的返回
    //---------------------------------------------------------
    var undefined = function(){}();

    //---------------------------------------------------------
    // 2. 代碼更簡潔,但不易懂的方法
    //---------------------------------------------------------
    var undefined = void 0;

    void也能像函數一樣使用,因此void(0)也是合法的。有些時候,一些復雜的語句可能不能
    使用void的關鍵字形式,而必須要使用void的函數形式。例如:
    //---------------------------------------------------------
    // 必須使用void()形式的復雜表達式
    //---------------------------------------------------------
    void(i=1);?????? // 或如下語句:
    void(i=1, i++);


    ?2). number類型
    ========================
    JavaScript中總是處理浮點數,因此它沒有象Delphi中的MaxInt這樣的常量,反而是有這
    樣兩個常值定義:
    ? Number.MAX_VALUE? : 返回 JScript 能表達的最大的數。約等于 1.79E+308。
    ? Number.MIN_VALUE? : 返回 JScript 最接近0的數。約等于 2.22E-308。

    因為沒有整型的緣故,因此在一些關于CSS和DOM屬性的運算中,如果你期望取值為整數2,
    你可能會得到字符串“2.0”——或者類似于此的一些情況。這種情況下,你可能需要用
    到全局對象(Gobal)的parseInt()方法。

    全局對象(Gobal)中還有兩個屬性與number類型的運算有關:
    ? NaN????? : 算術表達式的運算結果不是數字,則返回NaN值。
    ? Infinity : 比MAX_VALUE更大的數。

    如果一個值是NaN,那么他可以通過全局對象(Gobal)的isNaN()方法來檢測。然而兩個NaN
    值之間不是互等的。如下例:
    //---------------------------------------------------------
    // NaN的運算與檢測
    //---------------------------------------------------------
    var
    ? v1 = 10 * 'a';
    ? v2 = 10 * 'a';
    document.writeln(isNaN(v1));
    document.writeln(isNaN(v2));
    document.writeln(v1 == v2);

    全局對象(Gobal)的Infinity表示比最大的數 (Number.MAX_VALUE) 更大的值。在JS中,
    它在數學運算時的價值與正無窮是一樣的。——在一些實用技巧中,它也可以用來做一
    個數組序列的邊界檢測。

    Infinity在Number對象中被定義為POSITIVE_INFINITY。此外,負無窮也在Number中被定
    義:
    ? Number.POSITIVE_INFINITY? : 比最大正數(Number.MAX_VALUE)更大的值。正無窮。
    ? Number.NEGATIVE_INFINITY? : 比最小負數(-Number.MAX_VALUE)更小的值。負無窮。

    與NaN不同的是,兩個Infinity(或-Infinity)之間是互等的。如下例:
    //---------------------------------------------------------
    // Infinity的運算與檢測
    //---------------------------------------------------------
    var
    ? v1 = Number.MAX_VALUE * 2;
    ? v2 = Number.MAX_VALUE * 3;
    document.writeln(v1);
    document.writeln(v2);
    document.writeln(v1 == v2);

    在Global中其它與number類型相關的方法有:
    ?isFinite()?? : 如果值是NaN/正無窮/負無窮,返回false,否則返回true。
    ?parseFloat() : 從字符串(的前綴部分)取一個浮點數。不成功則返回NaN。


    ?3). boolean類型
    ========================
    ?(略)

    ?4). string類型
    ========================
    JavaScript中的String類型原本沒有什么特殊的,但是JavaScript為了適應
    “瀏覽器實現的超文本環境”,因此它具有一些奇怪的方法。例如:
    ? link() : 把一個有HREF屬性的超鏈接標簽<A>放在String對象中的文本兩端。
    ? big()? : 把一對<big>標簽放在String對象中的文本兩端。
    以下方法與此類同:
    ? anchor()
    ? blink()
    ? bold()
    ? fixed()
    ? fontcolor()
    ? fontsize()
    ? italics()
    ? small()
    ? strike()
    ? sub()
    ? sup()

    除此之外,string的主要復雜性來自于在JavaScript中無所不在的toString()
    方法。這也是JavaScript為瀏覽器環境而提供的一個很重要的方法。例如我們
    聲明一個對象,但是要用document.writeln()來輸出它,在IE中會顯示什么呢?

    下例說明這個問題:
    //---------------------------------------------------------
    // toString()的應用
    //---------------------------------------------------------
    var
    ? s = new Object();

    s.v1 = 'hi,';
    s.v2 = 'test!';
    document.writeln(s);
    document.writeln(s.toString());

    s.toString = function() {
    ? return s.v1 + s.v2;
    }
    document.writeln(s);

    在這個例子中,我們看到,當一個對象沒有重新聲明(覆蓋)自己toString()方
    法的時候,那么它作為字符串型態使用時(例如被writeln),就會調用Java Script
    環境缺省的toString()。反過來,你也可以重新定義JavaScript理解這個對象
    的方法。

    很多JavaScript框架,在實現“模板”機制的時候,就利用了這個特性。例如
    他們用這樣定義一個FontElement對象:
    //---------------------------------------------------------
    // 利用toString()實現模板機制的簡單原理
    //---------------------------------------------------------
    function FontElement(innerHTML) {
    ? this.face = '宋體';
    ? this.color = 'red';
    ? // more...

    ? var ctx = innerHTML;
    ? this.toString = function() {
    ??? return '<Font FACE="' + this.face + '" COLOR="' + this.color + '">'
    ????? + ctx
    ????? + '</FONT>';
    ? }
    }

    var obj = new FontElement('這是一個測試。');

    // 留意下面這行代碼的寫法
    document.writeln(obj);


    ?5). function類型
    ========================
    javascript函數具有很多特性,除了面向對象的部分之外(這在后面講述),它自
    已的一些獨特特性應用也很廣泛。

    首先javascript中的每個函數,在調用過程中可以執有一個arguments對象。這個
    對象是由腳本解釋環境創建的,你沒有別的方法來自己創建一個arguments對象。

    arguments可以看成一個數組:它有length屬性,并可以通過arguments[n]的方式
    來訪問每一個參數。然而它最重要的,卻是可以通過 callee 屬性來得到正在執行
    的函數對象的引用。

    接下的問題變得很有趣:Function對象有一個 caller 屬性,指向正在調用當前
    函數的父函數對象的引用。

    ——我們已經看到,我們可以在JavaScript里面,通過callee/caller來遍歷執行
    期的調用棧。由于arguments事實上也是Function的一個屬性,因此我們事實上也
    能遍歷執行期調用棧上的每一個函數的參數。下面的代碼是一個簡單的示例:

    //---------------------------------------------------------
    // 調用棧的遍歷
    //---------------------------------------------------------
    function foo1(v1, v2) {
    ? foo2(v1 * 100);
    }

    function foo2(v1) {
    ? foo3(v1 * 200);
    }

    function foo3(v1) {
    ? var foo = arguments.callee;
    ? while (foo && (foo != window)) {
    ??? document.writeln('調用參數:<br>', '---------------<br>');

    ??? var args = foo.arguments, argn = args.length;
    ??? for (var i=0; i<argn; i++) {
    ????? document.writeln('args[', i, ']: ', args[i], '<br>');
    ??? }
    ??? document.writeln('<br>');

    ??? // 上一級
    ??? foo = foo.caller;
    ? }
    }

    // 運行測試
    foo1(1, 2);


    2. JavaScript面向對象的支持
    --------
    在前面的例子中其實已經講到了object類型的“類型聲明”與“實例創建”。
    在JavaScript中,我們需要通過一個函數來聲明自己的object類型:
    //---------------------------------------------------------
    // JavaScript中對象的類型聲明的形式代碼
    // (以后的文檔中,“對象名”通常用MyObject來替代)
    //---------------------------------------------------------
    function 對象名(參數表) {
    ? this.屬性 = 初始值;

    ? this.方法 = function(方法參數表) {
    ??? // 方法實現代碼
    ? }
    }


    然后,我們可以通過這樣的代碼來創建這個對象類型的一個實例:
    //---------------------------------------------------------
    // 創建實例的形式代碼
    // (以后的文檔中,“實例變量名”通常用obj來替代)
    //---------------------------------------------------------
    var 實例變量名 = new 對象名(參數表);


    接下來我們來看“對象”在JavaScript中的一些具體實現和奇怪特性。

    ?1). 函數在JavaScript的面向對象機制中的五重身份
    ?------
    “對象名”——如MyObject()——這個函數充當了以下語言角色:
    ? (1) 普通函數
    ? (2) 類型聲明
    ? (3) 類型的實現
    ? (4) 類引用
    ? (5) 對象的構造函數

    一些程序員(例如Delphi程序員)習慣于類型聲明與實現分開。例如在delphi
    中,Interface節用于聲明類型或者變量,而implementation節用于書寫類型
    的實現代碼,或者一些用于執行的函數、代碼流程。

    但在JavaScript中,類型的聲明與實現是混在一起的。一個對象的類型(類)
    通過函數來聲明,this.xxxx表明了該對象可具有的屬性或者方法。


    這個函數的同時也是“類引用”。在JavaScript,如果你需要識別一個對象
    的具體型別,你需要執有一個“類引用”。——當然,也就是這個函數的名
    字。instanceof 運算符就用于識別實例的類型,我們來看一下它的應用:
    //---------------------------------------------------------
    // JavaScript中對象的類型識別
    //?? 語法:? 對象實例 instanceof 類引用
    //---------------------------------------------------------
    function MyObject() {
    ? this.data = 'test data';
    }

    // 這里MyObject()作為構造函數使用
    var obj = new MyObject();
    var arr = new Array();

    // 這里MyObject作為類引用使用
    document.writeln(obj instanceof MyObject);
    document.writeln(arr instanceof MyObject);

    ================
    (未完待續)
    ================
    接下來的內容:

    2. JavaScript面向對象的支持
    --------

    ?2). 反射機制在JavaScript中的實現
    ?3). this與with關鍵字的使用
    ?4). 使用in關鍵字的運算
    ?5). 使用instanceof關鍵字的運算
    ?6). 其它與面向對象相關的關鍵字

    3. 構造與析構

    4. 實例和實例引用

    5. 原型問題

    6. 函數的上下文環境

    7. 對象的類型檢查問題

    ?

    posted on 2006-03-20 09:40 Web 2.0 技術資源 閱讀(410) 評論(0)  編輯  收藏 所屬分類: Javascript
    主站蜘蛛池模板: 亚洲第一二三四区| 中文字幕亚洲电影| 噜噜噜亚洲色成人网站∨| GOGOGO免费观看国语| 免费精品国产自产拍观看| 无码天堂va亚洲va在线va| 国产真人无遮挡作爱免费视频| 亚洲AV无码一区二区三区人| 成年在线观看网站免费| 亚洲免费观看在线视频| 九九九精品成人免费视频| 中文无码亚洲精品字幕| 青草草在线视频永久免费| 欧洲亚洲综合一区二区三区| 一本色道久久88综合亚洲精品高清| 国产精品亚洲一区二区三区| 日韩精品亚洲专区在线观看| a级毛片免费网站| 亚洲色偷拍另类无码专区| 久久久久免费精品国产| 亚洲嫩模在线观看| 免费看成人AA片无码视频羞羞网| 亚洲人成综合网站7777香蕉| 国产精品免费看香蕉| 人人爽人人爽人人片av免费| 亚洲精品制服丝袜四区| 无码少妇精品一区二区免费动态 | 免费的全黄一级录像带| 亚洲三级电影网址| 黄色片在线免费观看| 国产成人综合久久精品亚洲| 亚洲午夜久久久久妓女影院| 8888四色奇米在线观看免费看| 最新亚洲春色Av无码专区| 免费吃奶摸下激烈视频| 久久精品一区二区免费看| 伊人久久亚洲综合影院首页| 久久青青草原亚洲av无码| av无码免费一区二区三区| 黄色a三级三级三级免费看| 久久亚洲私人国产精品vA|