免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
針對 Java 開發(fā)人員的 Dojo 概念

針對 Java 開發(fā)人員的 Dojo 概念

聲明類并設(shè)置上下文

Dave Draper, WebSphere Application Server Administrative Console 開發(fā)人員, WSO2 Inc

簡介: Dojo 在基于 Web 的應(yīng)用程序中越來越受到歡迎。很多開發(fā)人員是 Java™ 編程方面的能手,但是在 JavaScript 方面卻缺乏經(jīng)驗。從強類型、面向?qū)ο蟮木幾g語言轉(zhuǎn)向動態(tài)的、弱類型腳本語言,開發(fā)人員需要經(jīng)歷概念躍遷帶來的困難。這種混亂使開發(fā)人員很難正確地聲明 Dojo 類。本文將幫助梳理這種混亂,解釋為何必須設(shè)置上下文,以及如何實現(xiàn)它。

發(fā)布日期: 2008 年 11 月 03 日 
級別: 中級 其他語言版本: 英文 
訪問情況 1110 次瀏覽 
建議: 0 (添加評論)

 平均分 (共 3 個評分 )

簡介

如果您是一名只有很少或根本沒有 JavaScript 經(jīng)驗的開發(fā)人員,在接觸 Dojo 時可能需要掌握一些必要的概念。Dojo 的一個主要問題是(在撰寫本文之際),它仍然處于其嬰兒期(版本 1.0 在 2008 年 2 月份才發(fā)布),并且可用的文檔仍然非常有限。本文將幫助您理解 Dojo 和 Java 代碼之間的聯(lián)系,使您在開發(fā)應(yīng)用程序時可以快速入手并掌握這個工具箱。

本文并沒有介紹如何獲得 Dojo 工具箱或一些必要的使用指令,因為已經(jīng)有大量的資源提供了此類信息。本文主要針對從 servlet 開發(fā)轉(zhuǎn)向 Dojo 的 Web 開發(fā)人員。

Ajax 資源中心

請訪問 Ajax 資源中心,這是有關(guān) Ajax 編程模型信息的一站式中心,包括很多文檔、教程、論壇、blog、wiki 和新聞。任何 Ajax 的新信息都能在這里找到。

JavaScript hash

需要面對的主要挑戰(zhàn)之一就是理解在調(diào)用 Dojo 函數(shù)時使用的語法,特別是 “hash” 或 JavaScript 對象。hash 被表示為使用逗號間隔的一組屬性,并且使用大括號括起。清單 1 顯示了一個簡單的例子,它聲明了一個包含 6 個屬性的 hash:一個字符串、一個整數(shù)、一個布爾值、一個未定義的屬性、另一個 hash 和一個函數(shù)。


清單 1. 示例 JavaScript hash
				
var myHash = {
    str_attr : "foo",
    int_attr : 7,
    bool_attr : true,
    undefined_attr : null,
    hash_attr : {},
    func_attr : function() {}
};			
                

注意,JavaScript 是弱類型的,因此盡管每個屬性被初始化為一個與其名稱相關(guān)的值,但仍然需要把 str_attr 屬性設(shè)置為一個整數(shù)或布爾值(或其他任何類型)。使用 dot 操作符可以訪問或設(shè)置 hash 中的每個屬性(參見清單 2)。


清單 2. 訪問和設(shè)置 hash 屬性
				
// Accessing a hash attribute...
console.log(myHash.str_attr);

// Setting a hash attribute...
myHash.str_attr = "bar";
                

myHash 的前四個屬性的含義不言自明。事實上,hash 可以擁有 hash 屬性,這并不奇怪。(可以將這看作類似于原語和對象的 Java 類)。這是需要理解的最后一個重要屬性。

函數(shù)和對象

盡管 Java 代碼中有一個 java.reflection.Method 類,但它實際上只充當方法的包裝器。在 JavaScript 中,該函數(shù)可以是任何可設(shè)置、引用和作為參數(shù)傳遞給其他函數(shù)的對象。通常,像在 Java 方法調(diào)用中聲明匿名 inner 類一樣,也需要在函數(shù)調(diào)用中聲明新函數(shù)。

Java 方法和 JavaScript 函數(shù)之間的另一個重要區(qū)別是 JavaScript 函數(shù)可以運行在不同的上下文中。在 Java 編程中,使用 this 關(guān)鍵字引用所使用類的當前實例。當在 JavaScript 函數(shù)中使用時,this 引用該函數(shù)運行的上下文。如果沒有指定,函數(shù)將在定義它的閉包中運行。

在最簡單的情況下,閉包可以被看作是使用大括號({})包含的任意 JavaScript 代碼。JavaScript 文件內(nèi)部聲明的函數(shù)可以使用this 訪問在文件主體中聲明的任何變量,但是在 hash 內(nèi)聲明的函數(shù)只能使用 this 引用在 hash 內(nèi)部聲明的變量,除非提供其他上下文。

由于經(jīng)常需要使用封閉的函數(shù)作為 Dojo 函數(shù)的參數(shù),因此理解如何設(shè)置上下文將省去大量的調(diào)試工作。

用于指定上下文的主要 Dojo 函數(shù)是 dojo.hitch。您可能從不使用 dojo.hitch,但必須了解它是 Dojo 的關(guān)鍵部分,很多函數(shù)都在內(nèi)部調(diào)用它。

清單 3 展示了上下文連接的工作原理(其輸出顯示在圖 1 中):

  • 在全局上下文(globalContextVariable)中定義一個變量,在一個 hash 上下文(enclosedVariable)中聲明另一個變量。
  • 函數(shù) accessGlobalContext() 可以成功訪問 globalContextVariable 并顯示其值。
  • 但是,enclosedFunction() 只可以訪問其本地變量 enclosedVariable(注意 globalContextVariable 的值顯示為 “未定義”)。
  • 使用 dojo.hitch 將 enclosedFunction() 連接到全局上下文,這樣就可以顯示 globalContextVariable(注意,enclosedVariable 現(xiàn)在為 “未定義”,因為它不是在運行 enclosedFunction() 的上下文中聲明的)。

清單 3. 閉包和上下文
				
var globalContextVariable = "foo";

function accessGlobalContext() {
    // This will successfully output "foo"...
    console.log(this.globalContextVariable);
};

var myHash = {
    enclosedVariable : "bar",
    enclosedFunction : function() {
                           // Display global context variable...
                           console.log(this.globalContextVariable);

                           // Display enclosed context variable...
                           console.log(this.enclosedVariable);
                       }
};

console.log("Calling accessGlobalContext()...");
accessGlobalContext();

console.log("Calling myHash.enclosedFunction()...");
myHash.enclosedFunction();

console.log("Switch the context using dojo.hitch...");
var switchContext = dojo.hitch(this, myHash.enclosedFunction);
switchContext();
            


圖 1. 上下文連接的工作原理
 

聲明類

聲明類的技巧

  • 盡管 myClass 是一個有效的名稱,但是最好使用完全限定類名的形式聲明名稱,例如com.ibm.dojo.myClass。這并不表示應(yīng)當把類部署到相對路徑 “./com/ibm/dojo/” 下的文件系統(tǒng);它只是減少了與其他類名沖突的幾率。
  • 在最后一個屬性之后絕不會出現(xiàn) ,(逗號),因為一些瀏覽器將忽略它(FireFox),但是其他瀏覽器(Internet Explorer)會將它彈出。這條規(guī)則也適用于 hash 對象的聲明。

為什么連接如此重要?您將在聲明 Dojo 類或創(chuàng)建自己的部件時體驗到它的重要性。Dojo 的一大功能就是能夠通過使用 dojo.connect 函數(shù)和內(nèi)置的 pub/sub 模型將對象 “連接” 起來。

類的聲明需要三個對象:

  1. 一個惟一的類名
  2. 用于擴展函數(shù)的父類(以及模擬多個繼承的 “混合” 類)
  3. 定義所有屬性和函數(shù)的 hash

清單 4 展示了最簡單的類聲明方式,清單 5 展示了該類的實例化。


清單 4. 基本的類聲明
				
dojo.declare(
   "myClass",
   null,
   {}
);


清單 5. 基本的類實例化 
				
var myClassInstance = new myClass();

如果希望聲明一個 “真正的”(即有用的)Dojo 類,那么一定要理解構(gòu)造函數(shù)。在 Java 代碼中,您可以通過使用各種不同的簽名聲明多個重載的構(gòu)造函數(shù),從而支持實例化。在一個 Dojo 類中,可以聲明一個 preamble、一個 constructor 和一個 postscript,但是在大多數(shù)情況下,您只需要聲明一個構(gòu)造函數(shù)。

  • 除非混合使用了其他類來模擬多個繼承,否則不需要用到 preamble,因為它允許您在 constructor 參數(shù)傳遞給擴展類和混合類之前對其進行處理。
  • postscript 產(chǎn)生了 Dojo 小部件生命周期方法,但對標準 Dojo 類沒有什么用處。

不一定要全部都聲明,但是要將所有值傳遞到類的實例中,就必須將 constructor 函數(shù)聲明為 minimum。如果 constructor 參數(shù)將被該類的其他方法訪問,必須將它們賦值給已聲明的屬性。清單 6 展示了一個類,它只將其中一個 constructor 參數(shù)賦值給一個類屬性,并嘗試在另一個方法中引用它們。


清單 6. 賦值構(gòu)造函數(shù)參數(shù)
				
dojo.declare(
    "myClass",
    null,
    {
        arg1 : "",
        constructor : function(arg1, arg2) {
                          this.arg1 = arg1;
                      },
        myMethod : function() {
                       console.log(this.arg1 + "," + this.arg2);
                   }
    }
);

var myClassInstance = new myClass("foo", "bar");
myClassInstance.myMethod();
            


圖 2. 賦值構(gòu)造函數(shù)參數(shù)的結(jié)果 
 

復雜的屬性規(guī)則

類屬性可以在聲明時進行初始化,但是如果使用復雜對象類型(例如 hash 或數(shù)組)初始化屬性,該屬性將類似于 Java 類中的公共靜態(tài)變量。這意味著任何實例無論在何時更新它,修改將反映到所有其他實例中。為了避免這個問題,應(yīng)當在構(gòu)造函數(shù)中初始化復雜屬性;然而,對于字符串、布爾值等簡單屬性則不需要這樣做。


清單 7. 全局類屬性
				
dojo.declare(
    "myClass",
    null,
    {
        globalComplexArg : { val : "foo" },
        localComplexArg : null,
        constructor : function() {
                          this.localComplexArg = { val:"bar" };                          
                      }
    }
);

// Create instances of myClass A and B...
var A = new myClass();
var B = new myClass();

// Output A's attributes...
console.log("A's global val: " + A.globalComplexArg.val); 
console.log("A's local val: " + A.localComplexArg.val); 

// Update both of A's attributes...
A.globalComplexArg.val = "updatedFoo";
A.localComplexArg.val = "updatedBar";

// Update B's attributes...
console.log("A's global val: " + B.globalComplexArg.val);
console.log("A's local val: " + B.localComplexArg.val);
            


圖 3. 類屬性
 

覆蓋方法

超類的方法可以通過使用相同的名稱聲明屬性來擴展。這里和重載無關(guān),因為 JavaScript 將忽略任何意外的參數(shù)并使用 null 代替任何缺失的參數(shù)。在 Java 代碼中,如果要調(diào)用被覆蓋的方法,就必須在超類上調(diào)用該方法(即 super().methodName(arg1, arg1);),但在 Dojo 中,將使用 inherited 方法(this.inherited(arguments);)。清單 8 展示了兩個已聲明的類,其中child 擴展了 parent,覆蓋了它的 helloWorld 方法,但是調(diào)用 inherited 來訪問 parent 的函數(shù)。


清單 8. 在 Dojo 中調(diào)用超類方法 
				
dojo.declare(
    "parent",
    null,
    {
        helloWorld : function() {
                         console.log("parent says 'hello world'");
                     }
    }
);

dojo.declare(
    "child",
    parent,
    {
        helloWorld : function() {
                         this.inherited(arguments); // Call superclass method...
                         console.log("child says 'hello world'");
                     }
    }
);

var child = new child();
child.helloWorld();


圖 4. 在 Dojo 中調(diào)用超類方法的輸出 
 

設(shè)置方法上下文

清單 9 展示了一個實例化后的 Java 類,它將字符串數(shù)組中的元素復制到一個字符串 ArrayList。顯然,使用清單 10 的代碼可以在 Dojo 中提供相同的功能(注意,在構(gòu)造函數(shù)中實例化 targetArray,防止它變成全局性的)。不幸的是,它將導致圖 5 所示的錯誤消息,因為在 dojo.forEach 方法調(diào)用中聲明的函數(shù)創(chuàng)建了一個閉包,該閉包將 this 定義為引用它本身。


清單 9. 在 Java 代碼中訪問類的作用域變量 
				
import java.util.ArrayList;

public class MyClass
{
    // Declare an ArrayList of Strings...
    private ArrayList<String> targetArray = new ArrayList<String>();

    public MyClass(String[] sourceArray)
    {
        // Copy each element of a String[] into the ArrayList...
        for (String val: sourceArray) 
        {
            this.targetArray.add(val);
        }
    }
}


清單 10. 在 Dojo 中缺失上下文 
				
dojo.declare(
    "myClass",
    null,
    {
        targetArray: null,
        constructor: function(source) {
                         // Initialise in constructor to avoid making global
                         this.targetArray = []; 

                         // Copy each element from source into target...
                         dojo.forEach(source, 
                                    function(item) {
                                        this.targetArray[this.targetArray.length] = item;
                                    });
                     },
    }
);

// This will cause an error!
var myClass = new myClass(["item1","item2"]);


圖 5. 在 Dojo 中缺失上下文的輸出
 

盡管 targetArray 并不是在函數(shù)包圍的上下文中定義的,但是可以將上下文定義為參數(shù)傳遞給 Dojo 函數(shù)。這意味著 this 關(guān)鍵字可以訪問在該上下文中聲明的任何對象(包括函數(shù))。清單 11 顯示了正確的實現(xiàn)(注意,增加的代碼用粗體表示)。


清單 11. 在 Dojo 中設(shè)置正確的上下文
				
dojo.declare(
    "myClass",
    null,
    {
        targetArray: null,
        constructor: function(source) {
                         // Initialise in constructor to avoid making global
                         this.targetArray = []; 

                         // Copy each element from source into target...
                         dojo.forEach(source, 
                                    function(item) {
                                        this.targetArray[this.targetArray.length] = item;
                                    }, this);
                     },
    }
);
                

上下文并不總是作為 Dojo 函數(shù)簽名中的相同參數(shù)傳遞的:

  • 在 dojo.subscribe 中,上下文是在函數(shù)聲明之前傳遞的(參見清單 12)。
  • 在 dojo.connect 中,應(yīng)該分別提供定義 trigger 方法和 target 方法的上下文。清單 13 展示了一個例子,其中 obj1 定義methodA 的上下文,而 obj2 定義 methodB 的上下文。對 obj1 調(diào)用 methodA 將導致對 obj2 調(diào)用 methodB。

清單 12. 在 dojo.subscribe 中設(shè)置上下文
				
dojo.declare(
    "myClass",
    null,
    {
        subscribe : function() {
                        dojo.subscribe("publication",
                                       this, 
                                       function(pub) { 
                                           this.handlePublication(pub);
                                       });
                    },

        handlePublication : function(pub) {
                                console.log("Received: " + pub);
                            }
    }
);
                


清單 13. 在 dojo.connect 中設(shè)置上下文
				
dojo.connect(obj1, "methodA", obj2, "methodB");

結(jié)束語

已習慣構(gòu)化 Java 代碼環(huán)境的開發(fā)人員將很難適應(yīng) JavaScript。但是 Dojo 提供了類聲明功能,使向客戶端開發(fā)過渡變得非常簡單。充分理解上下文,以及何時、如何設(shè)置上下文,將為 Java 開發(fā)人員省去很多麻煩,并幫助他們自信地將 JavaScript 添加到自己的工具箱中。


參考資料

  • 您可以參閱本文在 developerWorks 全球網(wǎng)站上的 英文原文。

  • 在 DojoToolkit.org 中可以找到所有入門信息和資源。

  • 通過 developerWorks 文章 JavaScript Development Toolkit 簡介(developerWorks,2008 年 5 月)了解更多基于 Eclipse 工具的信息,這有助于編寫 JavaScript。

  • 瀏覽 技術(shù)書店,查找有關(guān)本文所述主題和其他技術(shù)主題的圖書。 

  • 在 developerWorks Ajax 資源中心 找到更多有關(guān)其他 Ajax 技術(shù)(包括 Dojo)的信息。

  • 還可以獲得有關(guān) Dojo API 的全部參考資料。

  • 從 Dojo 專區(qū) 獲得一些優(yōu)秀的 Dojo 編程示例。

關(guān)于作者

Dave Draper 的照片

在過去六年,Dave Draper 一直擔任 WebSphere Application Server Administrative Console 的開發(fā)。他是經(jīng)過 Sun 認證的 Web Component 開發(fā)人員,在基于 Web 的工具開發(fā)方面具有豐富的經(jīng)驗。

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
使用 Dojo 進行批量 Ajax 請求的多種處理方式
javascript前端面試題及答案整理
五個典型的 JavaScript 面試題
前端基礎(chǔ)進階(三):變量對象詳解
深入理解JavaScript系列(10):JavaScript核心(晉級高手必讀篇)
JavaScript
更多類似文章 >>
生活服務(wù)
分享 收藏 導長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服