|
월간 마이크로소프트웨어 2006년 12월
------------------------------------------------------------------------------------------------------------------
C#으로 만드는 자바 스크립트, Script#
한용희 woom33@paran.com
롯데정보통신 정보기술연구소에 재직 중이며, 닷넷 기반의 여러 프로젝트에 참여했다. 현재 Microsoft Visual C# MVP이며 MSDN 세미나 강사로도 활동 중이다. 처음에는 2D,3D 게임 프로그래머로 시작하여 SQLServer 튜닝, 응용 애플리케이션 개발에 이르끼 까지 다양하게 경험하였으며, 주요 관심사는 DB와 애플리케이션의 연동부분 이다.
운영체제 │ 윈도우 2003, 윈도우 XP
개발도구 │ Microsoft Visual Studio 2005
기초지식 │ ASP.NET, C#
응용분야 │ 모든 웹 응응프로그램
웹2.0의 시대가 오면서 사용자들은 점점 편리한 사용자 인터페이스를 맛보게 되었다. 이렇게 편리한 기능은 주로 클라이언트 언어인 자바스크립트를 통해서 이루어 지는데 자바스크립트라는 것이 스크립트 언어이다 보니 개발자들의 입장에서는 여간 불편한 것이 아니다. 아무리 해도 생산성이 높아지지 않는 것이다. 하지만 이제는 Script#을 이용하면 C#으로 자바 스크립트를 만들 수 있다. 또한 이렇게 만든 자바 스크립트는 MS기반뿐만 아니라 자바기반과 같은 다른 곳에서도 다 사용이 가능하다.
2004년 10월 미국 샌프란시스코에서 열린 “웹 2.0 컨퍼런스”를 통해 웹2.0의 개념이 전 세계에 소개된 이후 웹2,0은 하나의 트랜드로 자리 잡았다. 일반 신문에서도 차세대 웹 환경으로 웹2.0을 소개할 정도이니 웹2.0이라는 개념이 그 만큼 대중적으로 인기를 끄는 키워드가 되었다는 것은 의심의 여지가 없을 것이다. 하지만 웹2.0이 무엇이냐라고 물어보면 한마디로 정의하기가 어렵다. 왜냐하면 웹2.0이라는 정의 자체가 여러 의미를 포함하고 있기 때문이다. 웹 2.0은 어떤 기술이나 특징을 구체적으로 설명하기 위해 나타난 것이 아니라, 미국에서 닷컴의 버블 붕괴이후 살아남은 기업들 (아마존, 구글, 이베이 등)의 특징을 찾아내서 이를 집대성한 개념이 웹2.0이기 때문에 명확한 정의가 있는 것은 아니다. 하지만 IT 서적을 출판하는 오라일리(O'Reilly)사의 팀 오라일 리가 2005년 가을에 웹2.0이 무엇인가(What is Web 2.0)라는 글( http://tim.oreilly.com/news/2005/09/30/what-is-web-20.html)을 통해 웹2.0의 특징을 7가지로 정리하였다.
그 내용은 방대하므로 여기서는 생략한다. 자세한 내용은 본지 2006년 5월호 “Inside Web 2.0"을 참고하기 바란다.
그 글의 핵심적인 내용으로는 “사용자 중심적이고 참여적인 환경, 단순하고 경량화된 설계, 개방된 구조” 등을 들 수 있다. 즉, 구글이나 아마존, 이베이는 기존 사이트와는 달리 사용자가 보다 편리하게 사용할 수 있는 환경을 구축하였고, 사용자가 스스로 참여하고 만들어 나갈 수 있는 열린 공간을 지향 했기 때문에 성공하였고 그래서 이들의 특징을 웹2.0으로 정의한 것이다.
웹2.0의 시대에서 개발자가 열광하는 AJAX
이들 특징을 가장 잘 구현할 수 있는 기술을 들자면 3가지를 들 수 있다. 바로 RSS, tag, AJAX이다. RSS는 기존 웹이 사용자들이 방문해서 봐야하는 수동적인 웹에서 사용자에게 직접 배달해 주는 적극적인 웹을 구축하는 기술이며, tag는 검색을 하는데 있어 단순 문장 검색이 아닌 키워드 검색을 제공하기 위한 방법이며, AJAX는 웹이 가진 한계를 극복하기 위한 클라이언트 기술이다. 이중에 개발자들이 가장 큰 관심을 보이면서 열광하는 기술은 바로 AJAX이다. AJAX를 이용하면 웹 사이트를 마치 윈도우 애플리케이션을 이용하는 것처럼 만들 수 있기 때문에 시각적으로 그 효과를 바로 확인 할 수 있다. AJAX는 (Asynchronous xxJavascript and XML)의 약자로 비동기 통신을 XML 데이터를 이용해서 하는 기술을 말한다. 웹 환경의 가장 큰 단점은 모든 화면을 전부 갱신해야만 새 데이터가 나온다는 것이다. 그렇기 때문에 사용자의 편의성이 많이 떨어진다. 하지만 이 AJAX를 이용하면 웹 화면을 전부 갱신하지 않고 부분 갱신만으로 새로운 데이터를 보여줄 수 있어서 사용자의 편의성이 크게 좋아진다.
AJAX의 약자에서 알 수 있듯이 AJAX는 자바 스크립트 기반의 기술이다. 자바 스크립트가 겉으로만 자바라는 명칭이 들어가 있지만 사실적으로는 자바 언어와 큰 관련이 없는 언어이다. 하지만 MS 입장에서는 자바라는 명칭 자체도 부담스러울 만큼 MS에게는 무시할 수 없는 라이벌이었다. 그래서 자바 스크립트가 유행할 무렵 MS에서는 비주얼베이직 기반인 VBScript라는 별도의 스크립트 언어를 만들기도 하였다. 하지만 VBScript는 자바 스크립트가 가진 모든 기능을 커버할 수 없었으며 MS의 익스플로러에서만 구동된다는 단점이 있었다. 자바 스크립트는 모든 브라우저에게 잘 작동된다는 호환성을 무기로 점점 발전하기 시작했다. 그러던 와중에 비동기 통신 기술이 결합되면서 AJAX라는 기술이 탄생하게 된 것이다. 이를 이용하여 화려한 웹 사이트를 만들 수 만들 수 있게 되었다.
그동안 자바 스크립트를 관망하였던 MS에서는 더 이상 관찰자의 입장을 고수할 수는 없었다. 사용자들은 이미 웹2.0의 조류를 타고 AJAX의 환상에 빠져들기 시작한 것이다.
AJAX에 대한 MS의 대처방안 ASP.NET AJAX
MS는 부랴부랴 AJAX을 수용할 준비를 하고 인도 출신의 아키텍트인 Nikhil Kothari를 중심으로 별도의 프로젝트를 준비했다. 코드네임을 Atlas라고 명명하고 사용자들이 보다 쉽게 AJAX 기능을 구현할 수 있도록 도와주는 기술을 개발하기 시작했다.
2006년 11월 현재 기존 Atlas 코드네임으로 진행했던 프로젝트의 정식 이름을 ASP.NET AJAX로 명명하고 베타2 버전이 나와있는 상태이다. 초기에는 AJAX의 비동기 통신 부분만 구현하기 쉽도록 라이브러리를 만들더니 요즘에는 아에 자바 스크립트의 기능을 응용한 컨트롤들까지 선보이고 있다. 즉, 기존에 자바 스크립트를 이용해서 번거롭게 구현했던 드래그앤드랍이나 팝업, 접히는 패널 기능등을 아에 컨트롤로 만들어서 그냥 갔다 놓기만 하면 사용할 수 있도록 편리하게 만들어 놓은 것이다. 즉, 웹 컨트롤들을 마치 윈도우 컨트롤처럼 쓸 수 있도록 만들어 가고 있는데, 베타2 버전에서는 그 컨트롤 개수만 28개에 이른다. 이들 컨트롤을 이용하기만 해도 이게 정말 웹 사이트인가라고 사용자들을 놀라게 할 수도 있을 정도이다. Atlas에 관해서는 본지에 여러번 소개가 되었으므로 자세한 내용은 2006년 4월호 “웹2.0으로 향하는 발걸음, Atlas"를 참고 하기 바란다.
Script#의 탄생
Atlas 프로젝트의 핵심 설계자인 Nikhil Kothari는 기존의 자바 스크립트를 대폭 개량하는 방법으로 Atlas를 만들었다. 자바 스크립트는 이름만 자바라는 타이틀을 달고 자바 문법을 차용했을 뿐, 언어 구조적으로는 자바와는 다른 언어이다. 객체지향언어라고는 하지만 완벽한 객체지향 개념이 포함되어 있지 않으며, 스크립트 언어가 가진 자유스러움은 한편으로는 표준화의 어려움을 제공하였다. 이를 이용해서는 AJAX의 자유로운 기능을 효과적으로 구현하기가 어려웠다. 여러 브라우저를 모두 지원하고 객체지향의 개념을 포함하고, 표준화된 코드 생성을 위해서 자바 스크립트를 기반의 별도의 코어 엔진을 만들었다. 이를 바탕으로 모든 Atlas의 자바 스크립트 코드를 표준화해서 만들었다. 그러다 보니 표준화된 코어 엔진은 일반적인 객체 지향의 언어의 형태를 어느 정도 갖추게 된 것이다. 이제는 아에 C#을 통해서 자바 스크립트를 만들어 낼 수 있지 않을까 하는 자신감이 바로 Script#이라는 언어를 만들게 된 동기가 되었다.
개발자들의 웹 프로그래밍을 크게 두가지 영역으로 나눌 수 있다. 서버 사이트 부분과 클라이언트 사이드 부분이다. 이중에서 개발자들이 힘들어 하는 부분이 바로 클라이언트 부분이다. 클라이언트 부분은 사용자 PC에서 작동해야 하기 때문에 그 기능을 스크립트로 구현해야 하는데, 스크립트 언어이다보니 인텔리센스 기능도 없고, 컴파일 시간에 에러를 잡아 낼 수도 없고, 결국은 만들어서 웹에 올려보아야 그 결과를 알 수 있다. 그렇기 때문에 생산력은 떨어지고 개발자들에게 아주 귀찮은 작업으로 치부되고 있다. 하지만 사용자들은 웹2.0의 시대에 접어 들면서 그 화려한 인터페이스에 감동하면서 그들의 눈높이는 점점 높아져만 갔다. 이제는 기본적인 웹컨트롤로 화면을 구성해서는 사용자들의 높아진 눈높이를 만족시키기 힘들어진 것이다. 따라서 이럴수록 더욱 많은 스크립트 코딩이 들어가게 되었으며, 어떤 경우에는 웹 프로젝트를 하는데 있어 비즈니스 로직에 집중하기 보다 사용자 인터페이스에 많은 노력을 들어야 하는 경우도 생겨서 본말이 전도되는 현상이 일어나곤 했다. 이러한 문제점을 어느 정도 해결한 것이 바로 ASP.NET AJAX(코드명 Atlas)의 컨트롤들이지만, 이들은 특정한 요구사항에 맞는 특정한 기능을 제공할 뿐, 스크립트 언어 자체에 대한 대안은 아닌 것이다.
결국 Nikhil Kothari는 이러한 문제점에 대한 해결책으로 아에 자바 스크립트를 사용하지 않고, 단지 C#으로 자바 스크립트 코드를 생성해 내는 방향으로 새로운 가능성을 제시한 것이다.
Script#의 구현 원리
C# 컴파일러는 소스 코드를 컴파일을 하면 중간코드인 MSIL 코드를 생성해 낸다. 하지만 Script#은 컴파일을 하면 같은 C# 코드를 자바 스크립트 코드로 생성해 낸다. 서버사이드 기술이 ASP.NET이냐 자바 기반이냐 상관없이 결과물이 스크립트 코드이기 때문에 어디에서나 사용할 수 있는 장점도 있다. 단 서버 사이드 기술이 ASP.NET이라면 약간 더 편하게 사용할 수 있다. 서버 사이드 기술이 ASP.NET이 아니라면 결과물을 자바 스크립트 파일인 JS파일로 받아서 사용하면 되고, 서버 사이드 기술이 ASP.NET인 경우에는 생성된 dll 파일을 서버 사이드 컨트롤에서 그대로 참조해서 사용할 수도 있다.
Script#을 이용하여 코딩을 하면 비주얼 스튜디오의 인텔리센스, 리팩토리링, 클래스 브라우저 기능을 모두 사용할 수 있다. 또한 C# 언어가 가진 객체지향 기능을 거의 그대로 사용할 수 있으며, 컴파일시에 대부분의 에러를 잡아 주므로 개발 생산성이 향상된다.
Script#은 닷넷 프레임웍의 기본 코어인 mscorlib.dll을 사용하지 않는다. 이 코어는 스크립트 코드를 생성해 내기에는 타입 구조가 방대하므로, 타입 구조를 간략화 시킨 ssorlib.dll을 참조하여 사용해야만 한다. 이 코어 부분이 스크립트에서는 sscorlib.js 파일에 구현되어 있는데, 객체지향 타입 시스템 그리고 BCL(Base Class Library) 부분인 Debug, StringBuilder, CultureInfo등의 클래스가 자바 스크립트로 구현되어 있다.
Script#을 컴파일 하기 위해서는 두가지 방법이 있다. 하나는 커맨드라인 유틸리티인 ssc.exe를 이용하는 것이고, 또 다른 방법은 msbuild를 이용한 방법을 사용하는 것이다. msbuild를 이용하는 방법은 비주얼 스튜디오 2005에서 새로 도입이 된 방법인데, 사용자가 컴파일 방법을 커스터마이징하여 사용할 수 있는 방법을 제공하는 기능이다. Script#은 결과물로 자바 스크립트 파일인 JS파일을 생성해야 하므로 커스터마이징된 컴파일 과정이 필요하다. msbuild를 이용한 방법을 적용하면 비주얼 스튜디오내에서 바로 결과물을 확인할 수 있으므로 커맨드라인 유틸리티 보다는 msbuild를 이용하는 방법이 더 편리할 것이다.
Script#의 설치
Script#은 Nikhil Kothari의 사이트인 http://www.nikhilk.net/ScriptSharpIntro.aspx 에서 다운로드 받을 수 있다. 2006년 9월 현재 0.1.6.0 버전이 나와 있다. 하지만 아직 자동 설치 프로그램을 제공하지 않으므로 압축을 풀고 수동으로 설치해야만 한다.
기본적으로 닷넷 프레임웍은 2.0이 준비되어 있어야 하며, 비주얼 스튜디오는 2005가 준비되어 있어야 한다. 처음에 압축을 풀면 많은 파일들이 나오는데 그 파일을 아래 디렉토리에 복사를 한다.
프레임웍 폴더에 복사 (c:\Windows\Microsoft.NET\Framework\v2.0.50727)
Ssc.exe |
커맨드 라인 컴파일러 |
nStuff.ScriptSharp.dll |
컴파일러와 msbuild 작업 |
nStuff.ScriptSharp.targets |
msbuild에서 사용하는 script#의 정의 |
sscorlib.dll/.xml |
mscorlib.dll에 대응하는 Script#의 라이브러리와 설명 |
Script.ScriptFX.Core.dll/.xml |
코어 스크립트 프레임웍과 설명 |
Script.ScriptFX.UI.Core.dll/.xml |
UI 스크립트 프레임웍과 설명 |
Script.ScriptFX.UI.AutoComplete.dll/.xml |
자동완성 구현 부문과 설명 |
Script.ScriptFX.Reflection.dll/.xml |
리플렉션 API와 설명 |
Script.ScriptFX.XDAjax.dll/.xml |
JSON프로토콜 부문과 설명 |
비주얼스튜디오 템플릿 폴더에 복사
(C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\ProjectTemplates\CSharp)
CSharp.Templates.zip |
Script#을 위한 프로젝트 템플릿이다. 압축을 풀어서 해당 폴더에 복사한다. |
Script# 폴더에 복사 (C:\Program Files\nStuff\ScriptSharp\v0.1.0.0)
nStuff.ScriptSharp.Web.dll |
ASP.NET의 Scriptlet 서버 컨트롤(웹 애플리케이션의 bin 폴더에 복사해서 사용) |
Scripts folder |
디버그와 릴리즈 버전의 스크립트 파일 |
ScriptSharp.pdf |
도움말 |
Samples.zip |
샘플 |
msbuild에서 target 파일로 nStuff.ScriptSharp.targets을 사용할 것인데, 이 파일을 안전한 파일로 등록을 해주어야만 나중에 경고 메시지가 안 나온다. 안전한 파일로 등록하기 위해서 nStuff.ScriptSharp.reg 파일을 더블클릭하면 자동으로 등록을 해준다.
또한 비주얼 스튜디오에게 새로운 프로젝트 템플릿이 등록되었다고 알려주어야 하므로 “devenv /installvstemplates"이라고 실행하면 새로운 템플릿 갱신을 한다.
이제 어떤 새로운 언어를 배우면 누구나 제일 처음하는 "Hello World!"를 출력하는 예제로 Script#의 맛을 보자.
Hello World!
비주얼 스튜디오를 시작하고 새로운 프로젝트로 Script#의 Script# Application을 선택하여 프로젝트를 만든다.
<그림2> Scipt# Application 프로젝트 템플릿
자동으로 기본적인 참조와 코드들이 만들어져 있을 것이다. Class1을 생성하는 부분에 아래와 같이 Hello World를 출력하는 부분을 넣어 보자.
namespace HelloWorld
{
public class Class1
{
private Class1()
{
Document.Body.InnerHTML = "Hello World";
}
public static void ScriptMain(Dictionary args)
{
Class1 myClass = new Class1();
}
}
}
이는 단순히 웹페이지에 Hello World를 출력하라는 구문이다. 비주얼 스튜디오를 이용하므로 인텔리센스 기능을 <그림3>처럼 편리하게 사용할 수 있다.
<그림3> 비주얼 스튜디오에서 인텔리센스 기능을 사용
이제 이를 컴파일 하면 bin 폴더에 자바 스크립트 파일인 JS파일이 같이 생성이 된다. 아래는 생성된 자바 스크립트 파일이다.
Type.createNamespace('HelloWorld');
////////////////////////////////////////////////////////////////////////////////
// HelloWorld.Class1
HelloWorld.Class1 = function HelloWorld_Class1() {
document.body.innerHTML = 'Hello World';
}
HelloWorld.Class1.scriptMain = function HelloWorld_Class1$scriptMain(args) {
var myClass = new HelloWorld.Class1();
}
HelloWorld.Class1.createClass('HelloWorld.Class1');
네임스페이스로 HelloWorld를 등록하고 있으며, HelloWorld네임스페이스안에 Class1이라는 클래스를 생성해서 Hello World를 출력하고 있다. 이제 이를 사용하는 웹 애플리케이션을 만들어 보자.
웹 사이트로 ASP.NET 웹 사이트를 하나 만들고 ASP.NET 뿐만 아니라, 다른 기술에서도 사용가능하다는 것을 보여주기 위하여 일반적인 HTML 파일인 helloworld.htm 파일을 하나 추가하자. 그 파일에 아래와 같이 코딩을 한다.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Untitled Page</title>
</head>
<!-- The Script# bootstrapper and core framework (must be included first) -->
<script type="text/xxjavascript" src="sscorlib.debug.js"></script>
<script type="text/xxjavascript" src="ssfx.core.debug.js"></script>
<!-- The Generated Script and initialization -->
<script type="text/xxjavascript" src="HelloWorld.js"></script>
<script type="text/xxjavascript">
ScriptFX.Application.Current.run(HelloWorld.Class1, {});
</script>
<body>
</body>
</html>
먼저 Script#을 사용하기 위해서는 Script#의 핵심 기능이 들어있는 두개의 js파일을 포함 시킨다. 두가지 버전이 있는데, 개발하는 동안에는 디버그 버전을 사용하는 것이 디버깅 하는데 좋다. 이들 스크립트 파일은 처음 설치할 때 (C:\Program Files\nStuff\ScriptSharp\v0.1.0.0)에 복사해 두었으므로 그 파일 중에서 sscorlib.debug.js, ssfx.core.debug.js 두개의 파일을 복사해 온다.
이전의 프로젝트에서 생성한 HellowWorld.JS파일도 복사해서 같은 웹프로젝트 폴더에 복사한다. 이제 이를 Script#의 명령어인 run 명령어를 이용하여 해당 클래스를 생성하면 Hello World가 출력된다. <그림4>는 실행한 결과이다.
<그림4> Hello World 출력 결과
결과에서 확인할 수 있듯이 결과물이 스크립트 코드이므로 꼭 ASP.NET이 아니어도 어떤 서버 환경에서도 다 적용이 가능하다는 것일 확인 할 수 있을 것이다. 이번에는 ASP.NET 환경에서 사용해 보자. ASP.NET 환경에서는 scriptlet이라는 서버 컨트롤을 사용할 수 있으므로 보다 편리하게 결과물을 만들 수 있다
이번에는 이전에 생성했던 프로젝트에서 Default.aspx파일을 아래와 같이 수정해 보자.
<body>
<form id="form1" runat="server">
<div>
<nStuff:Scriptlet runat="server" ID="scriptlet" EnableScriptDebugging="true"
ScriptAssembly="HelloWorld"
ScriptletType="HelloWorld.Class1">
</nStuff:Scriptlet>
</div>
</form>
</body>
</html>
HelloWorld 어셈블리에서 Class1이라는 클래스를 등록하여 사용한다는 코딩을 하였다. 하지만 nStuff라는 태그는 원래 ASP.NET에 없는 태그이므로 이 태그를 해석할 수 있는 Script#의 nStuff.ScriptSharp.Web.dll과 HelloWorld의 dll인 HelloWorld.dll도 Bin 폴더에 복사한다. 그리고 Web.config에 아래와 같이 등록을 한다.
<configuration>
<system.web>
<compilation debug="true">
<assemblies>
<add assembly="System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
</assemblies>
</compilation>
<pages>
<controls>
<add tagPrefix="nStuff" assembly="nStuff.ScriptSharp.Web" namespace="nStuff.ScriptSharp.Web.UI"/>
</controls>
</pages>
</system.web>
</configuration>
전체적인 프로젝트의 모습은 <그림5>처럼 나올 것이다.
<그림5> ASP.NET의 서버 컨트롤을 이용한 프로젝트 모습
이제 이를 실행하면 처음과 같이 Hello World를 출력하는 모습을 볼 수 있을 것이다. 이제는 Script#을 이용하여 코딩을 하면 자바 스크립트로 어떻게 변환되는지 몇가지 예를 들어 보자.
Script#의 예제들
Eval 구문
// C#
string code = "2*4";
object result = Script.Eval(code);
// Java script
var code = '2*4';
var result = eval(code);
자바 스크립트에서는 전역 메소드를 사용 할 수 있다. 하지만 C#에서는 안 된다. 그러므로 Script.Eval이라는 명령어를 통해서 자바 스크립트로 변환이 된다.
Alert구문
// C#
Script.Alert("Good night!");
// Java script
alert('Good night!');
클래스 구현
// C#
public class Person
{
private string _name;
public Person(string name)
{
_name = name;
}
public string Name
{
get { return _name; }
set { _name = value; }
}
}
...
Person a = new Person("han");
// Java script
ScriptSharpEx1SiteCode.Person = function ScriptSharpEx1SiteCode_Person(name) {
this._name = name;
}
ScriptSharpEx1SiteCode.Person.prototype = {
_name: null,
get_name: function ScriptSharpEx1SiteCode_Person$get_name() {
return this._name;
},
set_name: function ScriptSharpEx1SiteCode_Person$set_name(value) {
this._name = value;
return value;
}
}
...
var a = new ScriptSharpEx1SiteCode.Person('han');
ScriptSharpEx1SiteCode.Person.createClass('ScriptSharpEx1SiteCode.Person');
클래스의 멤버는 prototype속성을 이용하여 늦은 바인딩을 수행하여 등록을 하고 있다. 또한 프로퍼티를 위한 get/set 메소드는 get_/set_ 접두사가 붙으면서 별도의 메소드로 명명이 되는 것을 확인할 수 있을 것이다.
상속 구현
// C#
public class Employee : Person
{
public string _team;
public Employee(string name, string team): base(name)
{
_team = team;
}
}
...
Employee a = new Employee("han", "Research");
// Java script
ScriptSharpEx1SiteCode.Employee = function ScriptSharpEx1SiteCode_Employee(name, team) {
ScriptSharpEx1SiteCode.Employee.constructBase(this, [ name ]);
this._team = team;
}
ScriptSharpEx1SiteCode.Employee.prototype = {
_team: null
}
...
var a = new ScriptSharpEx1SiteCode.Employee('han', 'Research');
ScriptSharpEx1SiteCode.Employee.createClass('ScriptSharpEx1SiteCode.Employee', ScriptSharpEx1SiteCode.Person);
자바 스크립트에서 클래스의 상속은 클래스 생성시 자신의 부모 클래스를 지정하고, 생성자에서 부모 클래스의 생성자를 호출하게 한다.
구조체 구현
// C#
public struct Point
{
public int x;
public int y;
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
}
...
Point p = new Point(10, 100);
// Java script
ScriptSharpEx1SiteCode.$create_Point = function ScriptSharpEx1SiteCode_Point(x, y) {
var $o = { };
$o.x = x;
$o.y = y;
return $o;
}
...
var p = ScriptSharpEx1SiteCode.$create_Point(10, 100);
구조체는 일반적으로 name/value와 같은 단순한 데이터를 표현하기 위한 레코드로 많이 사용한다. Script#에서도 구조체를 이용하여 JSON(xxJavaScript Object Notation)과 같은 경량의 데이터 교환 형식으로도 사용할 수 있다.
Point p = (Point) ScriptFx.JSON.Deserialize(data);
int x = p.x;
위의 예제처럼 네트웍으로부터 온 데이터를 풀어서 구조체에 넣고 사용할 수 있다.
열거형의 구현
// C#
public enum Colors { Red = 100, Green = 200, Blue = 300 };
...
Colors c = Colors.Red;
// Java script
ScriptSharpEx1SiteCode.Colors = Type.createEnum(false, 'ScriptSharpEx1SiteCode.Colors', { Red: 100, Green: 200, Blue: 300 });
...
var c = ScriptSharpEx1SiteCode.Colors.Red;
열거형은 sscorlib.js에 있는 Type.createEnum API를 통해서 구현할 수 있다. 한가지 참고할 것은 디버그 버전과 릴리즈 버전에서 생성되는 스크립트가 다르다는 것이다. 디버그버전과 릴리즈버전의 가장 큰 차이점은 공백이 존재하냐 안 하느냐의 차이점이다. 릴리즈 버전은 클라이언트가 가장 작은 JS파일을 로드하게 하기 위하여 모든 공백을 제거하고 JS파일을 생성한다. 열거형에 있어서는 문자 개수를 줄이기 위하여 아에 변환된 값을 만든다. 위의 경우 var c = 100; 과 같이 직접 결과를 넣어주는 방식으로 스크립트를 만든다.
Foreach구문의 구현
// C#
string[] items = { "1", "2", "3", "4" };
foreach (string s in items)
{
kkk += s;
}
Dictionary table = new Dictionary();
table["one"] = 1;
table["two"] = 2;
table["three"] = 3;
table["four"] = 4;
foreach (DictionaryEntry entry in table)
{
kkk += entry.Value.ToString();
}
// Java script
var items = [ '1', '2', '3', '4' ];
var $enum1 = items.getEnumerator();
while ($enum1.moveNext()) {
var s = $enum1.get_current();
kkk += s;
}
var table = {};
table['one'] = 1;
table['two'] = 2;
table['three'] = 3;
table['four'] = 4;
var $dict1 = table;
for (var $key2 in $dict1) {
var entry = { key: $key2, value: $dict1[$key2] };
kkk += entry.value.toString();
}
IEumerate 객체인 Arrays, Dictionaries와 같은 객체는 foreach 구문으로 열거를 할 수 있다. Script#에서는 두가지 방식으로 스크립트 코드를 만들어 내는데, DictionaryEntry를 사용하느냐 안하느냐에 따라 위와 같이 for 구문과 while 구문으로 나타낸다.
여기에서 지면 관계상 많은 예제를 다루지 못한다. 더 많은 내용은 Script#의 가이드 파일을 참고하기 바란다.
Script#의 한계
Script#은 C# 언어와 자바 스크립트언어 두가지 모든 부분을 다 충족하지는 못한다. 근본적으로 C#이 자바 스크립트와 같을 수 없기 때문에 두가지 언어에서의 공통적으로 커버할 수 있는 부분만을 지원한다.
Script#은 닷넷 프레임웍의 모든 기능을 다 지원하지는 않는다. 예를 들면 닷넷 프레임웍에서 윈폼같은 부분은 전혀 사용하지 못한다. 또한 Script#은 C# 언어의 부분집합이다. 결과물을 스크립트로 생성해 내야 하기 때문에 C# 언어의 모든 기능을 다 사용할 수가 없다. 예를 들면 out,ref와 같은 키워드를 사용할 수 없고, goto나 yield와 같은 구문을 사용할 수 없다.
자바 스크립트의 측면에서도 Script#은 몇가지 제한적인 특징을 가지고 있다. 자바 스크립트는 전역 메소드를 지원한다. 하지만 C#에는 그런 개념이 없다. 따라서 Script#에서는 자바 스크립트의 전역 메소드들을 System.Script 클래스안에 묶어 두었다. 또한 자바 스크립트는 식별자로 $를 사용할 수 있지만, C#에서는 안되므로 Script#에서 사용자가 식별자로 $를 사용할 수 없다. 대신 $는 내부적으로 자바 스크립트를 생성할 때 사용한다.
마치면서
웹 개발자에게 있어 스크립트는 귀찮고 어려운 작업중의 하나이다. 하지만 사용자의 다양한 요구사항을 만족시켜주려면 스크립트 코딩이 늘어날 수 밖에 없었다. 스크립트 코딩에는 인텔리센스 기능도 지원 안되고, 컴파일 타임에 오류 체크도 안되는 등 많은 불편한 점 때문에 생산성은 향상되지 못하고 있다. 그렇다고 자바 스크립트 언어에 인텔리센스 기능을 넣기도 어려웠다. 자바 스크립트 언어 자체가 늦은 바인딩을 지원하기 때문에 처음부터 선언 없이도 마구 사용 가능하기 때문이다.
이러한 불편을 Nikhil Kothari는 자바 스크립트를 아에 직접 코딩하지 않고, C#으로 코딩을 한 다음에 결과물을 자바 스크립트를 생성하도록 만들었다. 이를 이용하면 자바 스크립트를 보다 편리하게 만들 수 있는 것이다. 아직 베타 버전이므로 자바 스크립트와의 이별을 고하기는 어렵지만, Script#의 새로운 도전은 지켜볼 가치가 있을 것이다.