用JScript.net寫.net應用程式

來源:互聯網
上載者:User

javascript是一門很神奇的語言,靈活,容易學習,而且概念很超前。但是現在似乎被釘死在了瀏覽器上,其實這個才是javascript被人最大的誤解。M$的.net平台提供了全功能的JScript支援,不過這個JScript還是符合ECMA標準的,跟M$對待其他國際標準的態度一樣,JScript添加了很多其他能力,好讓人不小心就綁死在了windows上。不過沒關係,我們這次的主題是寫一個.net程式,綁死了也無所謂。誰讓我是“向M$投降派”呢,其實我根本上是不跟錢過不去(我們幫主叫做“上官金紅”-----熟悉嗎?)

安裝了.net SDK就預設安裝了JScript的編譯器jsc.exe了。在正式使用之前,我們要設定一個整合的編譯環境,bigtall用UltraEdit,所以在菜單“進階/工具配置”裡邊建立了一個命令:功能表項目名稱為“JScript.net編譯”;命令列為C:\Windows\Microsoft.NET\Framework\v2.0.50727\jsc.exe /fast- "%f" ;工作目錄為 %p;還要記得把“輸出”設定為“輸出到列表框”,儲存即可。

有了環境之後,我們可以開始編寫一些測試代碼了。首先建立一個test.js吧,標準的javascript代碼:

var arr = ["a","b"];
var obj = {name:"test", value:3.0};

print(arr[0]);
print(arr[1]);
print(obj.name);
print(obj.value);

執行以下剛才的功能表命令,編譯成功。在目前的目錄下出現了一個test.exe,運行,正常!

如果要編一個完整的程式,恐怕一個檔案就不夠了,所以我們測試一下多個檔案的編譯,建立一個mod.js檔案,內容如下:

function hello()
{
    this.name = "haha";
}

function haha()
{
    print("call haha");  
}

然後我們修改test.js如下:

var arr = ["a","b"];
var obj = {name:"test", value:3.0};

print(arr[0]);
print(arr[1]);
print(obj.name);
print(obj.value);

import mod;

var t = new hello();
print(t.name);

不過編譯可是有學問了,我們要用手工編譯了,進入cmd,輸入jsc  /fast- mod.js test.js編譯出一個mod.exe檔案來,運行,通過!但是如果我們用命令jsc /fast- test.js mod.js編譯,出來的test.exe就無法運行,究其原因是找不到mod.js中的東西。這是一個要注意的地方。

因為JScript做了很多擴充,我們要測試一下擴充命令和非擴充之間是否可以互相協作,因為我們要編.net下的程式,免不了要和.net SDK打交道,用擴充當然必要了。於是建立新檔案pkg.js,內容如下:

import System;
package France.Paris {
   public class Landmark {
      static var Tower : String = "Eiffel Tower";
      function p()
      {
        System.Console.WriteLine({t:"hello from writeline"}.t); 
      }
   }
};

然後我們把test.js修改如下:

var arr = ["a","b"];
var obj = {name:"test", value:3.0};

print(arr[0]);
print(arr[1]);
print(obj.name);
print(obj.value);

var t = new hello();
print(t.name);

haha();

print(France.Paris.Landmark.Tower);

import France.Paris;
new Landmark().p();

使用命令列jsc /fast- mod.js pkg.js test.js編譯出mod.exe,運行結果如下:

D:\work\testjs.net>jsc /fast- mod.js pkg.js test.js
Microsoft (R) JScript Compiler version 8.00.50727
for Microsoft (R) .NET Framework version 2.0.50727
Copyright (C) Microsoft Corporation 1996-2005。著作權所有,並保留一切權利。

D:\work\testjs.net>mod
a
b
test
3
haha
call haha
Eiffel Tower
hello from writeline

D:\work\testjs.net>

接下來,我們還要做一個工作。因為從實際的javascript編程中,我們有幾個不方便的地方,一個是編輯,eclipse下遊JsEclipse,但是.net下沒有,好在vs2008出來了,問題不大了;第二就是調試,出奇的困難,firefox下有外掛程式,很好。ie下也有,但是不太好用,經常抓不住斷點,但是從vs2005開始也湊胡了,只是大了一點而已。第三個就是js語言本身的問題了,好在有現成的擴充庫prototype,其他的幾個庫dojo,ext,jquery也都用過,只有prototype是純面向js語言本身的擴充,其他幾個跟瀏覽器綁定太緊密,用不了。所以我們接下來就要編譯prototype 1.5作為我們的擴充庫了。

首先從這裡擷取prototype1.5的代碼,用ultraedit裝入,然後運行開頭設定的“JScript.net編譯”命令,出現一堆錯誤。不要緊,我們做如下的兩個工作即可:

  1. 全文、全詞、大小寫敏感尋找替換set為_set,get為_get, event為ev
  2. 產生compitable.js檔案,內容如下:

    function fn(func):Function{return func;}

    var document = {
        getElementById: function(){ return null;},
        createElement: function(){return {appendChild:function(){}};},
        createTextNode: function(){return {};},
        getElementsByTagName: function(){ return []; },
        addEventListener:function(){},
        write:function(){},
        all: [],
        body: {},
        documentElement: {}
        };
    var window = {
        scrollTo:function(){},
        setTimeout: function(){},
        attachEvent:function(){},
        clearInterval:function(){},
        setInterval:function(){},
        location:{href:""},
        pageXOffset:0,
        pageYOffset:0
        };

    var navigator = {
        userAgent: "",
        appVersion:""
        };

  3. 使用命令列jsc /debug /fast- mod.js pkg.js compitable.js prototype.1.5.js test.js編譯,會有一堆警告和6個錯誤,都是在prototype中的類似function() { this.respondToReadyState(1) }.bind(this)的錯誤,把他們修改成fn(function() { this.respondToReadyState(1) }).bind(this)。估計原因可能是JScript編譯器的一個bug,沒能在這個環境下識別出function其實就是Function類型。
    如果使用的是最新的prototype1.6,除了上述幾步外,還要大小寫敏感替換this.Element為Element,把1555行var element = this.Element修改為var element = typeof Element == "undefined" ? {} : Element;把3845行wrapper.handler = handler;替換為fn(wrapper).handler = handler;即可。

接下來我們修改test.js檔案,如下:

var arr = ["a","b"];
var obj = {name:"test", value:3.0};

print(arr[0]);
print(arr[1]);
print(obj.name);
print(obj.value);

var t = new hello();
print(t.name);

haha();

print(France.Paris.Landmark.Tower);

import France.Paris;
new Landmark().p();

var instance = {
    funca: function(){return "funca";},
    funcb: function(){return "funcb";}
    };
Object.extend(instance, {
    funcb: function(){return "override funcb";},
    funcExt: function() { return "funcExt";}
    });
print(instance.funca());
print(instance.funcb());
print(instance.funcExt());

重新編譯,運行即可。

有一點小經驗bigtall要給大家分享:如果程式運行有異常,一般都是值為null引起的,JScript的異常報告不明確。

另外,prototype中dom相關的部分,ajax部分的代碼都不能使用,setTimeout,alert等函數也不能用,除非你擴充我的compitable.js。

基本的JScript.net協助參考這裡,同樣內容在VS2005的msdn協助裡邊也有。

實際上,要真正用JScript.net來做案頭應用,還需要對.net做一個介面層才行,不過bigtall個人認為如果按照winform的介面規範來走,JScript就失去了優勢,以js這麼靈活,應該有一個全新的介面庫。大家可以參考一下Ruby的GUI,Python的GUI庫的做法,有興趣的可以看這個文章。

結論

通過使用參數/fast-,並且替換少許保留字之後,JScript可以編譯大部分的傳統js代碼,並且可以和JScript.net的擴充文法同事使用。這就給我們用JScript來編製實際的應用程式建立了基礎。

結合目前js領域的語言擴充庫(目前只用了prototype),可以給JScript.net編程提供極大的方便性。但是目前JScript.net尚欠缺一個真正適合js特性的GUI庫,XML庫。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.