DragDicN: 네이버 사전

DragDicD: 다음 사전

DragDicY: 야후 사전



 만든지 정말 오래된 것이지만..
 Chrome이 IE보다는 크롬을 더 많이 쓰기 시작한 시점에서 더욱 유용해졌습니다.
 그래서 Chrome에 더 잘 맞도록 수정했습니다. (추가 버튼 색상을.... )

 사용법은...
 1. Boomarklet을 Browser에 등록 합니다.
 2. 사전에 찾아 보고 싶은 단어를 마우스로 Drag합니다. (옵션)
 3. 설치한 북마클릿(Bookmarklet)을 클릭 합니다.





 4. 그럼 아래와 같은 창이 뜹니다.



 5. 단어 뜻을 봤으면 .. 창을 닫아 버리면 됩니다. (옵션)




Posted by U_Seung



이번에는 Element Object에서 어떻게 this가 활용되는지 알아 보겠습니다.
지난번 글에서 this가 Object 내부의 함수에서 사용(evaluation)될 때, this가 해당 Object를 참조한다는 것을 알아 보았습니다.

마찬가지로, Element Object내의 함수에서 this가 사용되면 this는 해당 Element를 참조하게 됩니다. HTML+JS 를 통해서 이를 살펴보도록 하겠습니다.


#1. HTML에서의 Event 등록과 JS에서의 Event 등록의 차이

<input id="button" type="button" />

function eventButtonClick() {
     element = document.getElementById("button");
    (this == window).print("this == window");
    (this == element).print("this == element");
}


document.getElementById("button").onclick = eventButtonClick;


(결과)
> this == window: false
> this == element: true


위와 같이 Script에서 onClick에 해당 함수를 넣을 경우에 해당 Button을 클릭하면, this가 해당 element 나오는 것을 알 수 있습니다.

<input id="button" type="button" onclick="eventButtonClick()" />


function eventButtonClick() {
   
element = document.getElementById("button");

   
(this == window).print("this == window");

   
(this == element).print("this == element");

}
(결과)
> this == window: true

> this == element: false


반면에.. HTML에서 해당 Event에 함수를 지정한 경우에는
해당 Button을 클릭할 때, this는 window가 나오는 것을 알 수 있습니다.




#2. 차이가 발생하는 이유

도대체 왜 이런 차이가 생기는 것일까요?
일단 Click 이벤트가 발생이 되면..
document.getElementById("button").onclick();
와 같은 방식으로 해당 이벤트 핸들러가 호출 됩니다.

이때 함수 내부에 어떠한 차이가 있는지 각각의 경우에 함수 내부의 모습을 출력 해보도록 하겠습니다.

<input id="button" type="button" onclick="eventButtonClick()" />

function eventButtonClick() {
   (this == window).print("this == window");
}

document.getElementById("button").onclick.print("HTML");
document.getElementById("button").onclick = eventButtonClick;
document.getElementById("button").onclick.print("Script");

(결과)
> HTML: function anonymous() { eventButtonClick(); }
> Script: function eventButtonClick() { (this == window).print("this == element"); }


Script에서 이벤트 메소드에 함수를 지정하면, 해당 함수 Object가 직접 할당 시키는 효과를 가지지만, HTML에서 함수를 지정하면 해당 부분이 String으로 되어 있기 때문에 함수 Object가 직접 할당 되지 않고, anonymous 함수 내부에서 evaluation 되는 형태로 지정되게 됩니다.

즉, Script에서 이벤트 등록을 위해서 실행 되는 코드는...

element.onclick = function() { alert(this); }

와 같다고 한다면. HTML에서 이벤트 등록을 위해서 실행되는 코드는..

var func = function() { alert(this); }
element.onclick = function() { func(); }

와 같이 된다고 할 수 있겠습니다.
엄연한 차이가 발생합니다. 지난번 글을 유심히 보셨으면 위 둘 사이의 차이가 쉽게 보이실 것 같습니다.





#3. HTML에서도 Element Object의 this를 사용하기

그렇다면 HTML에서 Event를 지정하면서 this가 현재 Object를 참고하고 싶게 한다면 어떻게 해야 할까요?

<input id="button" type="button" onclick="eventButtonClick(this)" />

function eventButtonClick(sender) {
    element = document.getElementById("button");
    (sender == element).print("sender == element");
    (sender == window).print("sender == window");
}

(결과)
> sender == element: true
> sender == window: false
 

위 처럼 HTML에서 this를 적어 주면 됩니다.
이는 마치 위의 예제 형태로 단순화 시켜서 나타내면..

var func = function(sender) { alert(sender); }
element.onclick = function() { func(this); }

위와 같은 형식이 되겠습니다.
왠지 적고나니 지난번 글의 중복인것 같아서..
아래에 재미난(?) 퀴즈를 하나... ;;


##. 보너스 퀴즈

<input id="button" type="button" value="Element Object" />


var
value = "Window Object";

var obj = function() {

    this.value = "Prototype Object";

    this.func = function() { this.value.print("Name"); };

    };

obj.value = "My Object";

obj.func = function() { this.value.print("Name"); }

document.getElementById("button").onclick = (빈칸)


위 코드에 보면 각 Object에 따라서 value값에
(A) Element Object
(B) Window Object
(C) Prototype Object
(D) My Object
의 네 개의 값이 들어 있습니다.

button을 눌렀을 때, (A)~(D)의 String이 출력되도록 할려면 빈칸에 어떤 코드가 들어가야 할까요?

Posted by U_Seung
저도 이번엔 링크 위주의 글을 하나 적어 봅니다.

요즘 Visual Studio 2008을 쓰는데 Javascript 기능이 매우 좋아진 것 같습니다.
다른 Visual Studio가 좋은 IDE임은 누구나 다 인정 하지만, 특히 Javascript 에서는 빛을 발한다는 느낌이 듭니다.

Visual Studio 2008에서는 Intellisense기능과 Syntax Check 기능이 강화되었습니다.
사실 Javascript 처럼 Cloure가 지원되는 언어들은 완벽하게 Intellisense를 지원하는데 한계가 있습니다만 Visual Studio가 나름 잘 지원해주는 것 같네요. Syntax Error Check는 자주 Syntax error가 나진 않지만 Run time error에 들어가기전에 한번 걸러준다는 점에서 매우 소중한 기능이고요.


자세한 내용은 아래에..

Javascript Intellisense in Visual Studio 2008
- VS 2008 JavaScript Intellisense
- JScript IntelliSense in Visual Studio Orcas
- More Javascript Intellisense with Visual Studio 2008 Beta 2


Javascript Intellisense for Silverlight
- Javascript Intellisense in VS 2008 for Silverlight 1.0 
- Silverlight 1.0 full Javascript Intellisense


Javascript Syntax Check
- JScript Syntax Check in Visual Web Developer 2008 Beta2



--

참, Visual Web Developer 2008 Expression Edition은 무료로 다운받아서 사용하실 수 있습니다.

Posted by U_Seung


 이번에는 Javascript의 기본 문법에 있는 this, new, prototype이 어떻게 Scope에 영향을 주는지 알아보겠습니다.


#1. This는 Evalute되는 순간이 중요

각각의 경우에 aa값이 어떻게 출력될 지 예상 해보세요.

var aa = 10;

function check1() { this.aa.print("check1"); };

var obj = {

    thisref: this,

    aa: 20,

    check1: check1,

    check2: function() { this.aa.print("obj.check2"); },

    innerObj: {

        thisref: this,

        aa: 30,

        check1: check1,

        check3: function() { this.aa.print("obj.innerObj.check3"); }

        }

    };

 

check1();

obj.check2();

obj.check1();

obj.innerObj.check3();

obj.innerObj.check1();

(obj.thisref == window).print("obj.thisref == window");

> check1: 10
> obj.check2: 20
> check1: 20
> obj.innerObj.check3: 30
> check1: 30
> obj.thisref == window: true

 this는 Object내의 Method로 된 함수 내에서 현재 Object를 참조하는 역할을 합니다.
this는 함수가 어디서 선언 되었느냐 보다는 함수가 어느 Object에서 Evaluation 되었느냐가 중요하며, Evaluation되는 순간의 현재 Object를 참조 합니다.

 아무런 한정자가 없는 함수나 변수는 가장 최상위 Object인 window Object의 하위 Node에 속하게 됩니다. 따라서 check1()으로 실행될 때는 마치 window.check1()으로 호출되는 것과 같은 효과를 가지게 되며 this.aa는 window.aa가 되어서 10의 값을 가집니다.
 obj.check2()와 obj.innerObj.check3() 경우의 this는 현재 자신의 Object를 참조 합니다.
 obj.check1()과 obj.innerObj.check1()의 경우가 약간 혼동을 주는 케이스 입니다. 분명 이 함수들은 동일한 Context를 가지는 check1을 호출하게 되지만 Evalutation되는 순간 참조하는 Object가 각각 다르기 때문에 다른 this값을 가지게 됩니다. ( 만약 this.aa가 아닌 aa라면 check1을 호출하는 세 함수는 같은 값(10)을 가집니다. )
 경우에 따라서는 임의로 참조하는 Object를 변경하고 싶을 때가 있습니다. 이럴 때는 call()이나 apply()를 사용하면 됩니다.


#2. new는 Function의 prototype으로 Object를 만든다

Javascript에서는 Class를 만드는데 prototypenew를 제공합니다. new operator를 이용하면, Function type의 변수를 가지고 Object를 생성할 수 있습니다. 이때, 생성되는 Object는 Function Object의 prototype property의 값을 기본값으로 가지고 있습니다.

var aa = 10;

var check = function() { this.aa.print("check()"); };

var func = function() { this.check(); }

func.aa = 20;

func.check = function () { this.aa.print("func.check()"); };

func.prototype.aa = 30;

func.prototype.check = function () {
                          this.aa.print("func.prototype.check()"); };

 

func();

func.aa.print("func.aa");

func.check();

var newFunc = new func();

newFunc.aa.print("(new func).aa");

newFunc.check();

> check(): 10
> func.aa: 20
> func.check(): 20
> func.prototype.check(): 30
> (new func).aa: 30
> func.prototype.check(): 30

헷갈리지 말아야 할 부분은 new operator는 prototype 부분을 기반으로 하여서 Object를 만들어 준다는 것입니다. Function type도 Object type에 기반하기 때문에 다른 값들을 추가할 수 있는데 이는 new 로 생성된 object와는 아무런 연관이 없습니다.



#3. 참조가 바뀌는 전환점

prototype으로 지정된 값들은 여러 개의 Object가 생성이 되었을 때, 같은 값은 공유하는 것일까요? 각각 다른 값을 가지고 있는 것 일까요?

var func = function(name) { this.name = name; }

func.prototype.aa = 10;

func.prototype.check = function () { this.aa.print(this.name); };

 

newFunc1 = new func("o1");

newFunc2 = new func("o2");

func.prototype.aa = 20;

newFunc1.check();

newFunc2.check();

newFunc1.aa = 30;

func.prototype.aa = 40;

newFunc1.check();

newFunc2.check();

> o1: 20
> o2: 20
> o1: 30
> o2: 40

위의 결과 처럼 새로 생성한 Object에서 물려받은 값을 변경하지 않을 때에는 원래의 prototype의 값을 참조하다가 생성한 Object에서 값을 변경하면 이 참조가 깨지게 됩니다. 이는 변수 뿐만 아니라 함수도 적용되는 것이므로 객체의 상속이나 Polymorphism을 구현할 때 알고 있으면 좋습니다.



#4. this를 바꾸는 Call과 Apply

Call()과 Apply()는 파라미터로 Array를 받는지 여부만 차이가 있고 기능은 같은 함수 입니다. 이 함수들은 호출되는 순간의 this를 바꾸는데 사용합니다.

function check(str) { this.aa.print(str); };
var
obj = {

    aa: 10,

    check: check

    };

var func = function() { this.aa = 20; };

func.prototype.check1 = function(str) { obj.check(str); };

func.prototype.check2 = obj.check;

 

var newFunc = new func();

newFunc.check1("indirect");

newFunc.check2("direct");

newFunc.check2.call(obj, "call");

check.apply(newFunc, ["apply"]);

> indirect: 10
> direct: 20
> call: 10
> apply: 20


그럼 즐~Javascript  !!
Posted by U_Seung


이번에는 지난번에 다룬 기본기를 바탕으로 하여서 OOP개념에 기초가 되는 간단한 Class와 Object를 만들어 보았습니다.


#1. 아주 기본적인 Counter

function MakeIncCounter(initialNumber)
{
     return function() { return ++initialNumber; };
}

counter1 = MakeIncCounter(20);
counter2 = MakeIncCounter(10);
counter1();
counter2();
counter1();
counter1().print("Counter1");
counter2().print("Counter2");

> Counter1: 23
> Counter2: 12

1씩 단조 증가하는 Counter를 만들어 보았습니다.
여기에서 재미있게 볼 부분은 initialNumber 부분 입니다. C/C++에서는 함수가 끝나면 함수 내에서 사용하던 변수들이 모두 소멸되지만 Javascript에서는 참조하고 있는 곳이 있다면 함수가 종료 되었다 하더라도 해당 Context의 변수가 소멸되지 않습니다.




#2. 기능이 조금 있는 Counter

앞의 Counter는 단순히 1씩 밖에 더하지 못하는 Counter였습니다. 여기에 기능을 조금 더 추가한다면 다음과 같이 할 수 있겠습니다.

function MakeCounter(initialNumber, steps)
{
     initialNumber = initialNumber || 0;
    
steps = steps || 1;
    
return {
    
     StartingValue: initialNumber,
    
     GetValue: function() { return initialNumber },
    
     Inc: function() { initialNumber += steps; },
    
     Dec: function() { initialNumber -= steps; }
    
};
}

counter = MakeCounter(20, 3);
counter.Inc();
counter.Dec();
counter.Dec();
counter.StartingValue.print("Counter(S)");
counter.GetValue().print("Counter(C)");

> Counter(S): 20
> Counter(C): 17

여기에서는 GetStartingValue와 GetValue의 차이점을 보실 수 있습니다. StaringValue는 MakeCounter()가 return할 때의 initialNumber의 값을 받고, GetValue는 initialValue의 현재 값을 받습니다.



#3. 가독성 높이기

약간의 코드의 가독성을 고려한다면 아래와 같이 작성할 수도 있겠습니다.

function MakeCounter(initialNumber, steps)
{
     initialNumber = initialNumber || 0;
     steps = steps || 1;
     var name;
     var currentCounter = initialNumber;

    
// Methods
     function SetName(value) { name = value; }
     function GetValue() { return currentCounter; }
     function SetValue(value) { currentCounter = value; }
     function GetSteps() { return steps; }
     function Inc() { currentCounter += steps; }
     function Dec() { currentCounter -= steps; }
     function Print() { currentCounter.print(name); }
     return {
          "StartingValue": initialNumber,
          "SetName": SetName,
          "GetValue": GetValue,
          "SetValue": SetValue,
          "GetSteps": GetSteps,
          "Print": Print,
          "Inc": Inc,
          "Dec": Dec
     };
}

counter1 = MakeCounter(100, 20);
counter1.SetName("C1");
counter2 = MakeCounter();
counter2.SetName("C2");
counter2.SetValue(20);

counter1.Dec();
counter1.Dec();
counter2.Inc();
counter2.Inc();

counter1.Print();
counter2.Print();

> C1: 60
> C2: 22


약간 그럴싸한 Class가 만들어 졌습니다. 하지만 Method를 통한 Member variable의 접근은 가능하지만 Property를 통한 접근은 불가능한 상태 입니다. Member variable이 모두 private이라고 생각한다면 문제가 없겠지만 public한 경우도 있을 수 있으니 이를 확장 해보도록 하겠습니다.


#4. This Object 만들기.

 Object의 안과 바깥에서 공통적으로 접근할 수 있도록 하기 위해서 thisObj라는 Object를 생성하고, 여기에 Properties와 Methods를 추가하는 방법을 택하였습니다.

function MakeCounter(initialNumber, steps)

{

     initialNumber = initialNumber || 0;

     steps = steps || 1;

    

     var thisObj = {};

    

     // Properties

     thisObj.StartingValue = initialNumber;

     thisObj.name = "";

     thisObj.currentCounter = initialNumber;

 

     // Methods

     function SetName(value) { thisObj.name = value; }

     function GetValue() { return thisObj.currentCounter; }

     function SetValue(value) { thisObj.currentCounter = value; }

     function Inc() { thisObj.currentCounter += steps; }

     function Dec() { thisObj.currentCounter -= steps; }

     function Print() { thisObj.currentCounter.print(thisObj.name); }

     var methods = {

          "SetName": SetName,

          "GetValue": GetValue,

          "SetValue": SetValue,

          "Print": Print,

          "Inc": Inc,

          "Dec": Dec

     };

    

     for (var name in methods)

         thisObj[name] = methods[name];

     return thisObj;

}

counter = MakeCounter(100, 20);
counter.Inc();
counter.currentCounter -= 15;
counter.currentCounter.print("Counter");

> Counter: 105


 이제 정말 Class다운 모양을 갖춘 것 같습니다. 아쉽게도 Javascript의 언어적인 한계상 C++등의 Compiler단에서 지원하는 private, protected등의 Encapsulation을 깔끔하게 적용하기에는 다소 무리가 있지만 그런대로 OOP 프로그램을 할 수준은 아닌가 생각이 듭니다. 물론 private member와 private static member를 구현한 유명한 Technique[각주:1]들이 있는데 별로 권장할 만한 방법은 아닌 것 같습니다..



#5. Class 기능 확장하기.

OOP에서 가장 기본적인 개념 중 하나가 상속(Inheritance) 입니다. 이 것도 좀 흉내를 내본다면 아래와 같이 할 수 있습니다. 새로 만든 ImprovedCounter는 기존의 Counter가 가진 단순 Inc(), Dec()에 parameter를 지정하여서 특정값을 증가하거나 감소 할 수 있도록 하였습니다.

function MakeImprovedCounter(initialNumber, steps)

{

     var thisObj = MakeCounter(initialNumber, steps);

     thisObj.SetName("Improved");

    

     thisObj._superInc = thisObj.Inc;

     thisObj.Inc = function(steps) {

         if (steps == undefined) thisObj._superInc();

         else {

             thisObj.currentCounter += steps;

         }

     }

    

     thisObj._superDec = thisObj.Dec;

     thisObj.Dec = function(steps) {

         if (steps == undefined) thisObj._superDec();

         else {

             thisObj.currentCounter -= steps;

         }

     }

    

     thisObj.Initialize = function() {

          thisObj.SetValue( thisObj.StartingValue );

     }

    

     return thisObj;

}

var imCounter = MakeImprovedCounter(100, 20);
imCounter.Dec();
imCounter.Initialize();
imCounter.Inc();
imCounter.Inc(-10);
imCounter.Print();

> Improved: 110


이상 여기까지 만들어본 Class들은 Scope에 대한 이해를 돕기 위해서 Javascript에서 지원한 prototype, this, new의 개념을 사용하지 않고 만들었습니다. 하지만 실제 프로그래밍을 한다면 Javascript에서 지원하는 좋은 문법들을 적절히 도입하고, Prototype.js와 같은 라이브러리를 사용하는 것이 바람직 합니다. (참조: Defining classes and inheritance - prototype.js)


Javascript로 OOP를 구현하는 데 참조할 만한 글은....

Object Oriented Programming in Javascript
Classical Inheritance in JavaScript
Classes in Jscript - Part I
Classes in JScript – Part II: Instance Properties / Methods & Class Properties / Methods
Classes in JScript – Part III: Class Hierarchy and Data Encapsulation


Posted by U_Seung



Javascript가 가장 어렵다고 느껴질때가 Scope가 헷갈릴 때가 아닐까 생각이 듭니다.
웬만큼 프로그램좀 짜봤다 싶은 사람도 헷갈리기 십상인게 Javascript Scope 입니다.

시간을 내어서 간단히 정리해보았습니다. 말로 정리하는 것은 정리하는 것도 어렵고, 나중에 보기도 힘들어서 예제를 중심으로 정리 하였습니다. 다른 분들도 도움이 되시기 바랍니다.



#0. 테스트를 위한 함수 추가
Object.prototype.print =
     function (comment) {
          comment = comment || "";
          document.writeln(comment+": "+this);
     };

실전에서 사용하기에는 좋은 방법은 아니지만, 테스트 코드 작성의 편의성을 위해서 아무것이나 print()를 하면 화면에 출력되도록 하는 함수를 만들었습니다. 아래 예제에서 사용되는 함수이니 참조하세요.








#1. var로 선언하지 않은 변수는 이전 Context를 참조한다.

function ScopeTest()

{

    score = 50;

    score.print("2nd");

}

 

var score = 10;

score.print("1st");

ScopeTest();

score.print("3rd");

1st: 10
2nd: 50
3rd: 50



function ScopeTest()

{

    var score = 50;

    score.print("2nd");

}

 

var score = 10;

score.print("1st");

ScopeTest();

score.print("3rd");

1st: 10
2nd: 50
3rd: 10


두 결과가 다르게 나오는 것은 var가 붙고 안 붙고 차이 입니다.

Javascript는 var로 선언한 변수 경우, Execution Context(이하 줄여서 Context)[각주:1]가 생성할 때 해당 Context에 변수를 생성 합니다. 만약 해당 Context에 선언되지 않은 변수명를 사용하면, 이전 Context들을 차례로 뒤지면서 해당 변수명을 탐색 합니다. 최상위 Context에서도 변수를 발견하지 못하면 변수는 undefined 값을 가지고 되고, assignment 구문에서 사용되었다면 해당 변수명을 가진 변수를 새롭게 생성합니다. ( 이때, 변수는 최상위 Context에 생성 됩니다.)

Javascript는 함수 호출이 일어나게 되면 새로운 Context를 하나 생성합니다. 그리고 이 Context는 함수가 선언된 곳 하위에 Chian으로 차례로 연결됩니다. 위의 두 번째 예제에서는 ScopeTest()라는 함수가 호출될 때, 새로운 Context가 생성이 되었고 이는 가장 최상위 Context의 하위에 연결 되었습니다. 이 곳에서 새로운 변수 score를  선언 하였기 때문에 최상위 Context의 score와 다른 변수가 만들어 졌습니다.






#2. 이전 Context에 있는 변수를 사용 하려면 ??

function ScopeTest()

{

    score = 20

    var score = 50;

    score.print("2nd");

}

 

var score = 10;

score.print("1st");

ScopeTest();

score.print("3rd");

1st: 10

2nd: 50

3rd: 10





function ScopeTest(context)

{

    context.score = 20

    var score = 50;

    score.print("2nd");

}

 

var score = 10;

score.print("1st");

ScopeTest(this);

score.print("3rd");

1st: 10
2nd: 50
3rd: 20


Javascript는 해당 Context 내의 위치에서 어디라도 한번이상 변수가 선언(var)되면, Context를 생성할 때 변수도 같이 생성 합니다. (즉, 함수 내부에서 var score를 가장 아래에서 선언을 하나 가장 위에서 선언하나 동일한 효과를 지닙니다.) 따라서, 첫번째 예제는 score 변수가 새롭게 생성 도기 때문에 최상위 Context에 있는 score를 접근할 수 없는 것입니다.

 코드의 가독성을 높이기 위해서는 함수 블럭의 최상위에서 변수 선언을 하는 것이 좋습니다.
 C나 C++처럼 쓰고 싶은 상황이라면, 새 블럭마다 사용하는 변수를 모두 선언 해주는 것이 좋습니다.

이전의 Context에 있는 변수를 접근하려면 어떻게 해야 할까요? 일단 이전의 Context에 접근할 수 있는 직접적인 방법은 없습니다. 위의 두번째 예제에서는 this를 써서 접근하는 것과 같은 흉내를 내보이지만 사실상 this는 (Object를 생성하지 않은 상황이라서) window와 동일한 효과를 지니며, ScopeTest() 함수 내부에서도 역시 context.scorewindow.score, this.score와 모두 동일하다고 볼 수 있습니다. ( 여기에 대한 자세한 사항은 깊게 언급할 수 없어서 넘어 갑니다. )








#3. 함수 파라미터로 선언한 변수들..

function ScopeTest(score)

{

    score = 20;

    score.print("2nd");

}

 

var score = 10;

score.print("1st");

ScopeTest(score);

score.print("3rd");

1st: 10
2nd: 20
3rd: 10


함수의 파라미터로 선언된 변수들은 함수가 호출될 때 생성되는 Context에 새롭게 생성 됩니다. 따라서 위의 예제에서는 ScopeTest() 함수가 호출되는 새로운 Context에 score 변수가 생성되기 때문에 var를 붙이지 않더라도 기존 Context의 변수와 분리됩니다.








#4. Context를 하나 더 만들기...

function ScopeTest1()

{

    var score = 20;   

    ScopeTest2();

    score.print ("2nd");

}

 

function ScopeTest2()

{

    score = 30;

}

 

var score = 10;

score.print("1st");

ScopeTest1();

score.print("3rd");

1st: 10
2nd: 20
3rd: 30

function ScopeTest1()

{

    var score = 20;   
    var
ScopeTest2 = function () { score = 30; };

    ScopeTest2();

    score.print("2nd");

}

 

var score = 10;

score.print("1st");

ScopeTest1();

score.print("3rd");

1st: 10
2nd: 30
3rd: 10


위의 두 예제가 어떻게 다른지 유심히 보시면 아실 것 같습니다. Context가 만들어 질 때, Scope Chain이 어떻게 연결되는지를 판단할 수 있어야 합니다. 중요한 것은 함수가 '어디서 호출 되느냐'가 아니라 함수가 '어디서 선언 되느냐'입니다.

두 번째 부분을 아래와 같은  InnerFunction 형태로도 나타낼 수 있습니다.

function ScopeTest1()
{
    var score = 20;
   
function ScopeTest2()
    {
        score = 30;
    }
    ScopeTest2();
    score.print("2nd");
}


좀 더 직관적으로 볼 수 있도록 도식화 해 보았습니다.
 
사용자 삽입 이미지


 위의 그림과 같이 위의 두 예제에서 ScopeTest2()에서 score 변수는 다른 Context의 것을 참조 합니다. (참조: window는 최상위 Context에 위치한 Global Object를 나타냅니다.  )






더 세부적이고, 기술적인 글은 Microsoft JScript 블로그의 Scope chain of JScript Functions을 참조하시면 도움이 되실 겁니다.


  1. ECMAScript Language Specification a-10 [본문으로]
Posted by U_Seung


네이버가 최근 스마트 에디터를 오픈했었지요.

[웹 편집기의 새로운 기준, 스마트 에디터의 8가지 똑똑한 기능]

1. html 편집,맞춤법검사까지 편리하고 똑똑한 블로그 글쓰기툴
2. 다양한 뷰로 사진을 재구성하자, 비주얼 스토리텔링 포토 업로더
3. 고화질, 와이드사이즈로 업그레이드 된, 동영상 업로더
4. 내 포스트에 대한민국 넣자, 지도 첨부
5. 날씨, 인물, 드라마 검색해서 바로 첨부하자, DB첨부
6. 리뷰, 요리, 여행 주제별로 딱맞게 쓰자, 템플릿 글쓰기
7. 스타일리시한 매거진 룩으로 포스팅하자, 포스트 레이아웃
8. 날릴 걱정없이 쓰고, 파일로 보관하자, 안전한 포스트 저장 기능


아주 기능이 많은데.. 그 중에서 html 에디터를 보면 색상 선택기가 있더라고요.


사용자 삽입 이미지


오~ 멋지더라고요. 뭔가 Photoshop 같은 느낌이랄까..
어떻게 했나 궁금해서 Source를 좀 까봤습니다.
IE에서는 MS에서 제공하는 Filter를 쓰고, 나머지는 Canvas를 썼습니다.

그리고, 소스를 보면.. Javascript로 UI Framework을 만들어서 썼던데..
자세히 보진 않았습니다만 나름 잘 구현한 것 같네요.
이름이 Jindo 네요..

Yahoo의 YUI 처럼 NHN도 NUI를 공개하려나요 ?!
공개한다면 재밌을 것 같은데 공식적으로 공개할지 잘 모르겠네요.


또 재미있는 것 중에 하나는. NHN에서 서비스를 할때, 감사하게도 전혀 Scrambling 시키지 않고 소스를 배포했다는 겁니다. 소스가 잘 보이네요.. 그래서 저도 Colorpicker를 사용해 봤습니다.
사용법은 간단해서 누구나 쉽게 사용하실 수 있을 것 같네요. ^^

사용자 삽입 이미지



끝으로, Gradiation이 들어간 Colorpicker 자체에 대해서..
어떻게 만드는지 궁금하시는 분들은 아래를 참조하세요.


Posted by U_Seung
사용자 삽입 이미지
왼쪽(혹은 오른쪽) 그림과 같이 블로그에 Silverlight를 기반으로 한 아날로그 시계를 추가하였다.

뭔가 Silverlight로 이름이 변경되어 정식 런칭을 눈 앞에 둔 시점에서 뭔가 재밌는 것을 만들려다가 여러가지 여건상의 문제로;; 그냥 예전에 만든 아날로그 시계를 블로그에 붙이기로 했다.

Silverlight가 깔리지 않은 사람은 아마 시계가 안보일 거에요.
Silverlight 2007 Feb CTP 버전은 여기에서 받으실 수 있으니 설치하셔서 멋진(?) 아날로그 시계를 감상 하세요. ^^ 다음에 시간이 되면 Vista Sidebar Gadget에서 다른 스킨도 추가시킬까 생각도 하고 있는데 시간이 나면 해보려고 합니다.

혹시 시계를 Tistory 블로그에 달고 싶으신 분이 계시면..

<s_sidebar_element>
<!-- Silverlight Clock -->
<div id="Wpfeclock">
<h3>Silverlight Clock</h3>
<iframe src="http://sparcs.org/~airlover/wpfe/Clock/" style='border:0px; width: 150px; height: 150px' frameborder='0'></iframe>
</div>
</s_sidebar_element>

관리자모드에서 스킨 편집 메뉴에 들어가셔서 위의 코드를 <s_sidebar_element> 사이에 끼워 넣으시고, 사이브바 관리 메뉴에서 원하시는 위치에 Drag&Drop 해주시면 됩니다.




Posted by U_Seung
받기: http://www.prototypejs.org/download
문서: http://www.sergiopereira.com/articles/prototype.js.html

CHANGE LOG
*1.5.0* (January 18, 2007)

* Add test to ensure Content-type header is set for simulated verbs. [sam]

* Fix Content-Type header for HTTP methods simulated with POST not defaulting to application/x-www-form-urlencoded. [Thomas Fuchs]

* Simplify form serialization and add support for fields with the same name as Hash methods. Closes #6649. [Mislav Marohni훶]

* Fix attribute selectors for IE. Closes #5170. [Tobie Langel, Andrew Dupont]

* A slew of dom.js improvements. Closes #4217, #6589, #7001. [Tobie]
- Fix Element.getDimensions() for hidden elements, make Element.getHeight() use .getDimensions()
- Add Element.getWidth()
- Make Element.replace() call .toString() on the html argument (alike .update())
- Fix an issue with Element.get/setStyle() and Safari with 'float'
- Add a bunch of missing unit tests

* Fix an issue with Element.setStyle({opacity:''}) setting the opacity to 0 instead of removing the set inline opacity style. [Thomas Fuchs]

* Ensure Ajax.Request's evalResponse is called before onComplete so that onComplete can reference any elements created during the response. Closes #6727. [jonathan]

* Ensure the WEBrick test runner sets the correct Content-Type for tests and fixtures. [sam]

* Form.serialize once again works with non-form elements. This is a temporary change to prevent the Rails link_to_remote regression described in #6898. Prototype 1.5.1 will introduce an API for working with collections of arbitrary form elements. References #6887. Closes #6898. [sam]

* Make selectors match forms that have an element with name="id" correctly, fixes #5759 [mislav]

* Remove support for HTTP authorization in Ajax calls introduced with #6366. Closes #6638 [jmecham]

* Add Enumerable.size() to count elements in an enumerable and the corresponding Array.size() method, fixes #6710 [ZenCocoon]

* Add String.succ() method to allow for String ranges, fixes #6037 [Cory Hudson, mislav]
Examples:
'abcd'.succ(); -> 'abce'
$R('a','d').map(function(char){ return char; }); -> ['a','b','c','d']

* Make Element.scrollTo() correctly consider offsets of parent DOM nodes, fixes #6625 [ohader, savetheclocktower]

* Fix Enumerable.inGroupsOf() to correctly work with fill values that evaluate to false, fixes #6782 [hawk]

* Remove/cleanup redundant $() calls in dom.js, fixes #6817 [Tobie]

* Don't cache files in automatic unit tests, fixes #6218 [voidlock]

* Add $w() to easily create arrays from strings like Ruby's %w, fixes #5682 [glazedginger, brendon.aaron]

* Add Element.toggleClassName() to toggle CSS classes on elements, fixes #6759 [Tobie]

* Make Form.getInputs always return an array for consistency, fixes #6475 [Justin Gehtland, savetheclocktower]

* Make TimedObserver work correctly for SELECT MULTIPLE elements, fixes #6593 [clemos, tdd]

* Fix Template.prototype.evaluate to correctly interpret 0 and false values, add String.interpret() for safely interpreting and converting values to strings, fixes #6675 [hawk]

* Make Element.getStyle() work with camelCased argument, fixes #6686 [Tobie]

* Fix a redundant check in Array.prototype.compact, fixes #4739 [wlodarcz, mislav]

* Fix $() to correctly pass back the results of document.getElementById(), notably returning "null" on elements not found, fixes #6582 [adsmart]

* Change/add assertNull, assertUndefined, assertNullOrUndefined and not-* variants in unittest.js, fixes #6582 [adsmart]

* Cleanup String.prototype.camelize, fix an issue with String.prototype.underscore, fixes #4714, #6685 [Tobie, Thomas Fuchs]

* Add String.prototype.capitalize, which returns a string with the first character in upper case, fixes #6666 [Tobie]

* Make Element.getStyle() and Element.setStyle() handle the CSS 'opacity' property transparently in IE, fixes #6093 [brandon.aaron, Tobie]

* Fix handling of CSS 'float' property for Element.getStyle() and Element.setStyle(), fixes #4160 [Thomas Fuchs, ericf]

* Fix that onComplete would be called twice with synchronous Ajax requests on Safari (provides units tests for #5756) [Thomas Fuchs]

* Fix Form.Field.activate to not select text on buttons in IE, fixes #2653 [sutch, mislav, Thomas Fuchs]

* Fix String.unescapeHTML() on Firefox for strings that are longer than 2048 bytes, fixes #5789 [Paul Moers, Thomas Fuchs]

* Redefine Array.prototype.concat for Opera, as the native implemenation doesn't work correctly [Thomas Fuchs]

* Add unit tests for Function.prototype.bind() [Thomas Fuchs]

* Add String.prototype.underscore and String.prototype.dasherize [Thomas Fuchs]
Examples:
'Hello_World'.dasherize() -> 'Hello-World'
'borderBottomWidth'.underscore() -> 'border_bottom_width'
'borderBottomWidth'.underscore().dasherize() -> 'border-bottom-width'

*1.5.0_rc2* (November 11, 2006)

* Ensure that existing DOM properties take precedence over extended element methods in all browsers. Closes #5115. [Sean Kleinjung, sam]

* Add Element.Methods.readAttribute as a simple wrapper around getAttribute (which isn't a "real" function and doesn't have .apply or .call in Safari and IE).
 Useful in conjunction with Enumerable.invoke for extracting the values of a custom attribute from a collection of elements. [sam]

Example:
<div id="widgets">
<div class="widget" widget_id="7">...</div>
<div class="widget" widget_id="8">...</div>
<div class="widget" widget_id="9">...</div>
</div>

$$('div.widget').invoke('readAttribute', 'widget_id')
// ["7", "8", "9"]

* Add Element.Methods.immediateDescendants, like $A($(element).childNodes) but without text nodes. [sam]

* More consistency. Closes #6573. [Bob Silva]

* String.prototype.toQueryParams and Hash.prototype.toQueryString now properly serialize arrays as multiple values. Closes #4436. [mislav, altblue, L`OcuS]

* Fix Form.serialize for options with empty values. Closes #5033. [tdd, Thomas Fuchs, sam]

* Add Element.Methods.Simulated for simulating HTMLElement methods in lesser browsers. Add hasAttribute as the first simulated method. [tdd, Thomas Fuchs, sam]

* Add a "retry with throw" button for test error messages. [sam]

* rake test now runs test/unit/*.html by default. Additionally, you can specify individual tests to run with the TESTS environment variable, and you can restrict the tests to particular browsers using the BROWSERS environment variable. [sam]

Examples:
% BROWSERS=safari,firefox rake test
% TESTS=dom rake test

* Element.hasClassName now bypasses the Element.ClassNames API for performance. [sam]

* Pick some low-hanging performance and DRYness fruit. [sam]
- Inline length property accesses in for loops
- Enumerable-ize for loops where it makes sense
- Make better use of Element.Methods and Form.Methods/Form.Element.Methods

* A slew of Ajax improvements. Closes #6366. [mislav, sam]

Public-facing changes include:
- HTTP method can be specified in either lowercase or uppercase, and uppercase is always used when opening the XHR connection
- Added 'encoding' option (for POST) with a default of 'UTF-8'
- Ajax.Request now recognizes all the JavaScript MIME types we're aware of
- PUT body support with the 'postBody' option
- HTTP authentication support with the 'username' and 'password' options
- Query parameters can be passed as a string or as a hash
- Fixed both String.toQueryParams and Hash.toQueryString when handling empty values
- Request headers can now be specified as a hash with the 'requestHeaders' option

* Improve performance of the common case where $ is called with a single argument. Closes #6347. [sam, rvermillion, mislav]

* Fix Object.inspect to correctly distinguish between null and undefined, fixes #5941 [tdd, mislav]

* Don't serialize disabled form elements, fixes #4586 [tdd]

* Make HTML element classes extension mechanism for Safari not throw errors on WebKit beta versions [Thomas Fuchs]

* Add support for using Element.update() with no or a non-string parameter [Thomas Fuchs]

Example:
$('empty_me').update() -> clears the element
$('easy_as').update(123) -> set element content to '123'

* Add unit tests for hashes, fixes #6344 [Tobie Langel]

* Add clone() method to arrays, fixes #6338 [Tobie Langel]

* Backing out of [5194] (Element.clear) because of issues with IE on certain elements, #6051

* Add Element.clear for easily emptying out elements, fixes #6051 [brandon.aaron@gmail.com]

* Enumerable.each now returns the enumerable to allow for method chaining, fixes #6250 [eventualbuddha]

* Make makeClipping and undoClipping always return their element to stay chainable

* Fix an issue with certain Element chain calls not correctly extending elements with Prototype element methods on IE [Thomas Fuchs]

* Add Enumerable.eachSlice and Enumerable.inGroupsOf, fixes #6046 [rails@tddsworld.com, Thomas Fuchs]

Example:
[1,2,3,4,5].inGroupsOf(3) -> [[1,2,3],[4,5,null]]
[1,2,3].inGroupsOf(4,'x') -> [[1,2,3,'x']]

* Complete unit tests for array.js and string.js [Thomas Fuchs]

* Performance improvements for document.getElementsByClassName, including querying with XPath in supported browsers. [Andrew Dupont]

* Make Form.getElements() return elements in the correct order, fix broken Form.serialize return, fixes #4249, #6172 [lars@pinds.com, Thomas Fuchs, john]

* Add various DOM unit tests, fixes #6176, #6177 [tdd]

* Split Form.serialize into Form.serialize and Form.serializeElements. The latter can be used stand-alone to serialize an array of elements you pass in, instead of the entire form [DHH]

* Form.Element.disable() and .enable() will now work correctly, fixes #6034 [dresselm@businesslogic.com]

* Fix IE and Safari issues with Position.positionedOffset, add position.html unit tests, fixes #5621 [renggli@iam.unibe.ch]

* Fix an issue with Element.undoClipping and IE [Thomas Fuchs]

* Element.cleanWhitespace now correctly removes consecutive empty text nodes, fixes #3209 [livier.duroselle@gmail.com]

* Element.extend now does not try to extend text nodes, fixes #4642 [siegfried.puchbauer@gmail.com]

*1.5.0_rc1* (September 4, 2006)

* bindAsEventListener now passes along any provided arguments after the event argument. Closes #5508. [todd.fisher@revolution.com]

* Fix makeClipping and undoClipping with local overflow style values other than visible and hidden, fixes #3672 [Thomas Fuchs]

* Add Element.up, Element.down, Element.previous, and Element.next for easily traversing the DOM. (Inspired by Thomas Fuchs' original implementation of Element.up: http://pastie.caboo.se/7702) [sam]

Examples:
<div id="sidebar"> -> $('nav').up() or $('menu').up('div')
<ul id="nav"> -> $('sidebar').down() or $('sidebar').down('ul') or $('menu').previous()
<li>...</li> -> $('sidebar').down(1) or $('sidebar').down('li')
<li>...</li> -> $('sidebar').down(2) or $('sidebar').down('li', 2) or $('sidebar').down('li').next('li')
<li class="selected">...</li> -> $('sidebar').down('li.selected')
</ul>
<ul id="menu"> -> $('sidebar').down('ul').next()
...

* Refactor $$ and Element.getElementsBySelector into Selector.findChildElements. [sam]

* Add Element.match, which takes a single CSS selector expression and returns true if it matches the element. [sam]

* Add Element.ancestors, Element.descendants, Element.previousSiblings, Element.nextSiblings, and Element.siblings. [sam]

* Add Element.inspect for better DOM debugging. [sam]

* Add an optional boolean argument to String.prototype.inspect which, when true, makes the string double-quoted instead of single-quoted. [sam]

* Add the uniq() method to Arrays, which returns a new Array with duplicates removed, fixes #3810 [secondlife]

* Add stop() method to PeriodicalExecutor, fixes #4801 [Jon Evans]

* Fix issues with Enumerable.any, ObjectRange.toArray, added unit tests, fixes #4419 [miyamuko, Thomas Fuchs]

* Fix two instances of unneccesarily redeclared variables, fixes #5229 [Thomas Fuchs]

* Fix a loop in Element.extend to properly use local variable, fixes #5128 [arrix]

* Add constants for additional keys in Event, fixes #5411, #5795 [simone_b]

* Workaround a DOM API bug in Opera in Position.page(), fixes #2407, #5848 [Thomas Fuchs]

* Remove duplicate definition of Position.clone(), fixes #3765 [Thomas Fuchs]

* Make destructive Element, Form, and Form.Element methods return their first argument, so that multiple calls can be chained together. [sam]

ex. $("sidebar").addClassName("selected").show();

The following methods now return their first argument: Element.toggle, Element.hide, Element.show, Element.remove, Element.update, Element.replace, Element.addClassName, Element.removeClassName, Element.observe, Element.stopObserving, Element.cleanWhitespace, Element.scrollTo, Element.setStyle, Element.makePositioned, Element.undoPositioned, Element.makeClipping, Element.undoClipping, Form.reset, Form.disable, Form.enable, Form.focusFirstElement, Form.Element.focus, Form.Element.select, Form.Element.clear, Form.Element.activate, Form.Element.disable, Form.Element.enable.

* For consistency, Element.toggle, Element.show, Element.hide, Field.clear, and Field.present no longer take an arbitrary number of arguments. [sam]

!! BACKWARDS COMPATIBILITY CHANGE !!

If you have code that looks like this:
Element.show('page', 'sidebar', 'content');
You need to replace it with code like this:
['page', 'sidebar', 'content'].each(Element.show);

* Mix in Form and Form.Element methods to forms and form field elements with $() and $$(). Closes #4448. [Dan Webb, sam]

* Add Object.clone [sam]

* Add Form.Element.disable and Form.Element.enable. Closes #4943. [jan@prima.de]

* Field is now simply an alias for Form.Element. [sam]

* Add Element.Methods.getElementsByClassName and Element.Methods.getElementsBySelector. Closes #4669. [Andrew Dupont, DHH, sam]

* Avoid race condition when stopping an Ajax.PeriodicalUpdater. Closes #4809. [e98cuenc@gmail.com]

* Improve support for synchronous requests. Closes #5916. [sam, jthrom@gmail.com]

* Add serialization and observation support for input type=search. Closes #4096. [rpnielsen@gmail.com]

* Properly decode query components in String.prototype.toQueryParams. Closes #3487. [sam]

* Add Array.prototype.reduce [sam]:
[1, 2].reduce() // [1, 2]
[1].reduce() // 1
[].reduce() // undefined

* Add Object.keys and Object.values [sam]

* Simulate non-GET/POST requests by POSTing with a _method parameter set to the actual verb [DHH]

* Make Element.update() handle TABLE-related elements with the DOM API because of IE's missing .innerHTML property on them [Thomas Fuchs, thx to Rick Olson]

* Sync to script.aculo.us unittest.js library as of 2006/08/29 [Thomas Fuchs]

* Add additional unit tests to test/unit/dom.html for testing Element.update and $().update in various enviroments [Thomas Fuchs]

* Prevent possible exceptions on unloading the page in IE [Thomas Fuchs]

*1.5.0_rc0* (April 5, 2006)

* Modify HTMLElement.prototype and short-circuit Element.extend where possible. Closes #4477. [Thomas Fuchs]

* Only observe window.onunload in IE for Mozilla bfcache support. Closes #3726. [Mike A. Owens]

* Don't redefine Array.prototype.shift. Closes #4138. [leeo]

* Prevent redefining Array.prototype.reverse more than once. Closes #3951. [brettdgibson@gmail.com]

* Fix Enumerable.min/Enumerable.max to recognize the value 0. Closes #3847, #4190. [rubyonrails@brainsick.com, Martin Bialasinski]

* Change Ajax.getTransport to prefer XMLHttpRequest in anticipation of IE 7. Closes #3688. [jschrab@malicstower.org, sam]

* Make Array.prototype.flatten more robust. Closes #3453. [Martin Bialasinski, sam]

* Fix evalScripts from crashing Firefox if script includes 'var'. Closes #3288, #4165. [rahul@ntag.com, sam]

* Scope iterators locally. Closes #4589. [sam]

* Support Insertion.Before/Insertion.After for <tr> elements in IE. Closes #3925. [rails-venkatp@sneakemail.com]

* Add a contentType option for overriding application/x-www-form-urlencoded in Ajax.Request. Closes #3564. [avif@arc90.com, sam]

* Surround values in the X-JSON header in parenthesis for better compatibility with Firefox. Closes #4118. [bigsmoke@gmail.com]

* Fix Form.serialize to properly encode option values in multiple selects in IE. Closes #3291. [rubyonrails@brainsick.com]

* Cache methods added to DOM elements with Element.extend to prevent memory leaks in IE. Closes #4465. [jaen@laborint.com, sam]

* 1.5.0_pre1* (March 26, 2006)

* Add attribute selector support for Selector (and $$). Closes #4368. [devslashnull@gmail.com]
Example:
$$('form#foo input[type=text]').each(function(input) {
input.setStyle({color: 'red'});
});

* Send Accept header containing 'text/javascript, text/html, application/xml, text/xml */*'' to inform Rails that we prefer RJS, but we'll take HTML or XML or whatever if you can't deliver the goods [DHH]

* Make $$ work in IE. Closes #3715. [rubyonrails@brainsick.com]

* Add test/browser.html, which provides a simple object browser for the Prototype source (Firefox/Safari only). [sam]

* Add Element.extend, which mixes Element methods into a single HTML element. This means you can now write $('foo').show() instead of Element.show('foo'). $, $$ and document.getElementsByClassName automatically call Element.extend on any returned elements. [sam]

* Add Element.replace as a cross-browser implementation of the "outerHTML" property. References #3246. [tom@craz8.com]

* Fix Enumerable.zip iterator behavior. [Marcin Kaszynski, sam]

*1.5.0_pre0* (January 18, 2006)

* Add String.prototype.truncate to complement the Action View truncate helper. [sam]

* Add String.prototype.gsub, String.prototype.sub, and String.prototype.scan, all of which take a pattern and an iterator (or a pattern and a replacement template string in the case of gsub and sub). [sam]

* Add a Template class for interpolating named keys from an object in a string. [sam]

* Add the $$ function for finding DOM elements by simple CSS selector strings. [sam]
Example: Find all <img> elements inside <p> elements with class "summary", all inside
the <div> with id "page". Hide each matched <img> tag.
$$('div#page p.summary img').each(Element.hide)

* Add a Selector class for matching elements by single CSS selector tokens. [sam]

* Add Test.Unit.Assertions.assertEnumEqual for comparing Enumerables in tests. [sam]

* Add Element.childOf(element, ancestor) which returns true when element is a child of ancestor. [sam]

* Fix escaping in String.prototype.inspect. [sam]

* Add String.prototype.strip to remove leading and trailing whitespace from a string. [sam]

* Move Prototype to Rails SVN. [sam]
http://dev.rubyonrails.org/svn/rails/spinoffs/prototype/

* Make the console nicer. [sam]

* Prune the source tree. [sam]




Posted by U_Seung
Fiddler


Fiddler is a HTTP Debugging Proxy which logs all HTTP traffic between your computer and the Internet. Fiddler allows you to inspect all HTTP Traffic, set breakpoints, and "fiddle" with incoming or outgoing data. Fiddler is designed to be much simpler than using NetMon or Achilles, and includes a simple but powerful JScript.NET event-based scripting subsystem.


Fiddler는 컴퓨터 상에서 네트워크를 통해서 주고 받는 HTTP를 모두 캡쳐하여 이를 보여주는 프로그램 입니다.
네트워크상의 Packet들을 캡처해서 보여주는 프로그램은 Fiddler 이외에도 좋은 프로그램이 많지만 Fiddler는 HTTP에 최적화된 프로그램으로 XML트리로 보기, 퍼포먼스 통계 보기등 다른 캡처프로그램에서 보기 힘든 기능도 제공합니다.


만든 프로그램이 제대로된 패킷을 날리는지 다른 프로그램이 어떻게 하는지 알고 싶을 때, 매우 유용 합니다.
자세한 도움말은 introduction to Fiddler on MSDN. 혹은 Performance Tuning with Fiddler를 참조하시면 됩니다.



Script Debugger for Windows NT 4.0 and Later
The Microsoft Script Debugger is a debugging environment that extends any Microsoft ActiveX® Scripting host application—for example, Microsoft Internet Explorer (IE) or Microsoft Internet Information Server (IIS).
웹프로그래밍을 하다보면 특히 Javascript or VBScript 등에서 디버깅을 하기가 매우 까다롭습니다.
무슨 파일의 몇 번째줄에서 죽었는지만 알아도 참 좋을텐데 말입니다. ^^ VS를 만든 회사답게 Script Debugger도 디버깅의 기본기능을 모두 담았습니다. 스크립트를 개발하는 사람이라면 꼭 써야할 필수품이지 싶습니다. (VS있으신 분은 말고용..^^)


Firebug

Firebug integrates with Firefox to put a wealth of development tools at your fingertips while you browse. You can edit, debug, and monitor CSS, HTML, and JavaScript live in any web page.
요즘에 한창 주가가 오르고 있는 프로그램 이지요. Firefox에도 기본적으로 DOM Inspector를 내장하고 있고, 이 프로그램도 매우 훌륭하지만 Firebug는 이 프로그램보다 n배쯤 더 훌륭한 프로그램인 것 같습니다. 특히 Style이 어떻게 Accumulating 되는지 보여주는 기능은 거의 감동에 가까운 기능입니다. (기존의 프로그램은 주로 결과로 보여주었습니다.)

그리고 마지막으로 별로 좋은 프로그램은 아니지만..
발전 가능성이 보이는 Internet Explorer Developer Toolbar Beta 3 도 쓸만합니다.
사실 IE에서는 IE DOM Inspector라는 프로그램이 쓸만한데 공짜라 아니라서 ㅠㅠ 아쉽지요..



'정보 공유터' 카테고리의 다른 글

날씨 RSS 서비스  (2) 2007/01/26
Prototype 1.5.0 출시..  (1) 2007/01/19
WPF: Yahoo (대박) Messenger for Vista  (2) 2007/01/15
유용한 웹 개발/디버깅 지원 도구 몇 가지  (0) 2007/01/14
Microsoft .Net Framework 3.0, WPF: NY News Reader  (0) 2006/09/24
Google Code Jam  (0) 2006/09/01
네이버 타이머  (0) 2006/08/26
Posted by U_Seung

우리 학교 전산학과 2학년에 Scheme을 배우는 과목이 있다. Scheme은 Functional Programming을 지원하는 언어로 우리가 주로 사용하는 C, JAVA 등의 Procedural programming과 또 다른 세계를 보여준다. 오늘은 비슷한 결과를 낼 수 있는 Javascript로 Scheme 스타일을 좀 따라해봤다.

이 둘 사이에는 여러가지 차이가 있는데 가장 큰 차이는 Functional Language가 Referential transparency를 제공한다는 점에 있다. 자세한 사항을 알아서 찾아보시고;;;

일단 예제 코드를 보자.


var cons = function(a, b) { return function (f) { return f(a, b); } };
var car = function(c) { return c(function(a, b) { return a;}) }
var cdr = function(c) { return c(function(a, b) { return b;})
매우 간단한 세가지 함수를 만들었다.


document.writeln( car(cons("a", "b")) );
document.writeln( car(cdr(cons("a", cons("b", "c")))) );
테스트를 해보면? 결과는 무엇이 나올까?


a
b
대충 짐작 했듯이 cons는 두 값을 pair로 만들어 주고,
car는 첫번째 값을 cdr은 두번째 값을 return하는 매우 심플한 예제다.








var list = function() {
  arg = arguments;
var helper = function(i) {
     if (arg.length == i) return null;
     return cons(arg[i], helper(i+1));
};
return helper(0);
}
var list_ref = function(items, n) {
return (n)? list_ref(cdr(items), n-1) : car(items);
}
var length = function(items) {
return (items)? length(cdr(items))+1 : 0;
}
머리가 아프더라도 마음을 비우고 보면, 가볍게 보인다.


list1 = list(1, 3, list(2, 4, 5), 7, 9);
document.writeln( list_ref(list1, 3) );
document.writeln( length(list_ref(list1, 2)) );
앞에서 만든 cons를 이용해서 list를 만들고, list에 있는 값들을 control하는 함수 들이다.


7
3
결과 위와 같이 7, 3이 출력되게 된다.
왜 그런지는 쉽게 생각할 수 있을 듯 하다.








var $plus = function(a, b) { return a+b; }
var $pair = function(item) {
try { a = car(item); b = cdr(item); } catch(e) { return false; }
return true;
}

var map = function(proc, items) {
return (items)? cons( proc(car(items)), map(proc, cdr(items)) ) : null;
}
var accumulate = function(proc, initial, items) {
return (items)? proc( car(items), accumulate(proc, initial, cdr(items)) ) : initial;
}
var count_leaves = function(t) {
return accumulate($plus, 0,
  map(function(a) { return ($pair(a)) ? count_leaves(a) : 1; }, t)
);
}
마지막은 그래도 재미있는 예제로.. map과 accumulate함수 그리고 이를 이용한 트리의 노드 개수를 세는 함수이다.


document.writeln( count_leaves(list ("+", 5, list("*", list("+", 3, 9) , 4) )) )


7
총 노드가 7개(+, 5, *, +, 3, 9 ,4)  이므로...

더 재미있는 예제들은.. 나중에...
혹은 여기를 참조하세요.
Posted by U_Seung

NGMap v0.6

내 생산물 2006/08/09 23:29

http://sparcs.org/~airlover/9eye.net/map/
에서 보시기바랍니다.

안타깝게도 호스팅 서비스에 문제가 생겨서
Tistory로 이전하면서 예전 글의 모습은 삭제 되었습ㄴ다.

Posted by U_Seung

NGMap v0.5

내 생산물 2006/08/04 09:47

http://sparcs.org/~airlover/9eye.net/map/index_v0.5.html

에서 보시기바랍니다.

안타깝게도 호스팅 서비스에 문제가 생겨서
Tistory로 이전하면서 예전 글의 모습은 삭제 되었습ㄴ다.

Posted by U_Seung