Regular Motion

개발자가 상팔자

Tag: JS

Getting Literal with Template Strings.

최근 개발하고 있는 기능 중, JavaScript에서 XML String을 생성하는 부분이 있다.  해당 코드는 Template화된 XML String에서, 필요한 값들을 replace하는 방식으로 구현되어 있었다.
문제는 Template에 replace 해야 할 값들이 많을 수록 코드의 미적인 부분과 성능적인 부분이 함께 추락하는 방식이었다.
아래의 코드는 위의 예시와 72% 정도 유사하다.

생성해야 할 XML Template을 String으로 선언한 뒤, 변수로 치환되어야 할 값들을 String.prototype.replace()를 통해 치환하는 구조다.  쉽고, 나름 직관적이다.  사실 크게 문제가 있는 코드라고 보기는 어렵다. 하지만 위에서 언급했듯 치환되어야 할 값들이 늘어나면 replace chaining이 늘어나며 뭔가 문제가 생길 것 같은 불안감을 내포하는 코드다.

그래서 위 코드를 깔끔하게 개선하고 싶어 약간의 조사를 해보니 ES6의 Template Strings을 활용하면 매우/훨씬 깔끔한 코드로 수정 가능 할 것 같았다.  (정말 약간의 조사로 알게되어 애초에 왜 저렇게 구현했나 자괴감이 들었다)

실제로 위 코드를 ES6의 Template Strings을 활용하여 수정한 코드는 아래와 같다.

문장을 감싸는 부호를 single quotes(‘)에서 back-ticks(´)으로 대체했고, 값들을 치환하는 replace() chaining 구문이 사라졌다. (JavaScript 엔진에 의해 자동으로 치환된다는 의미다.)
코드가 간결해졌다는 것은 시력이 0.2 이상인 사람은 모두 육안으로 확인 가능하고, 성능이 빨라졌다는 것은 간단한 Benchmark를 통해 증명 가능하다.  (https://jsfiddle.net/6xnutcsd/)
* 위의 예제는 크롬에서 7~10배 정도의 성능 향상이 있으며, 치환되어야 할 값들이 많을수록 성능 개선 효과도 크게 나타났다.

 

예제로 글을 시작했으니, 이제 문법과 활용 범위에 대해 알아보자.
(글 끝부분의 Reference 링크를 참고하시는게 더 낫다)

Syntax
Template String은 일반적으로 String을 감쌀 때 사용하던 single quote(‘)나 double quote(“) 대신 back-ticks(`)을 사용하면된다.  쉽다;


String Substitution
문자열에 JavaScript Expression을 삽입 할 수 있는 String Substitution은 Template String의 가장 큰 장점이라고 할 수 있다. 심지어, 거의 모든 JavaScript Expression이 허용되며,  치환/처리가 필요한 Expression을 중괄호{}로 감싼 뒤, 앞에 달러($)를 붙여주기만 하면 된다. (아, 이놈의 자본주의, 그놈의 돈돈돈)

Expression에는 단순히 변수의 이름이나, 간단한 수식은 물론이고, Instance의 property나 method등 일반적인 JavaScript Expression 대부분 허용된다. (개발자한테 참 좋은데, 설명할 방법이 없다.)

Tagged Templates
Tagged Templates은 함수를 이용하여 Template String의 출력을 변형하기 위한 목적으로 사용 할 수 있다. 사용법은 함수의 이름 뒤에 Template String을 선언하면 된다. 그러면 함수의 첫번째 인자로 Template String의 문자열이 Array 형태로 전달되고, Expression이 순서대로 함수의 인자로 전달된다.

상상력이 미천한건지 아직까지 Tagged Templates의 활용할 코드는 발견하지 못했다.

 

References

 

[Javascript] addEventListener와 관련하여.

일반적으로 아래와 같은 방법으로 DIV Element에 Event Listener를 등록하면,

normalHandler (Callback)이 호출될 때 this는 Element 자신을 가르키게 된다.

즉, EventListener로 함수를 넘겨주게 되면, Callback이 호출될 때의 Context는 Element자신이 된다.

이 방법은 Callback안에서 Element의 id나 class, value에 접근해야 하는 경우 유용하다.

하지만 Touch Scroll 이나 Drag 같은 기능은 Callback의 Context를 원하는 Object로 정의했을 때 편한 경우가 많이 있다.

그럴 때는 handleEvent를 속성으로 갖는 instance를 넘겨주면 Callback으로 instance의 handleEvent가 호출되며,

Callback에서의 this는 instance를 가르킨다.


라잇댓. addEventListener의 2번째 인자로 function이 아닌 Instance를 전달!

Instance의 prototype에 handleEvent가 정의되어 있기 때문에 Callback을 받을 수 있다.

MUST CHECK WHAT ‘THIS’ IS. & XY INCREAMENT.



iScroll에서 이와 같은 방법으로 Scroll을 처리하는 코드


iScroll의 prototype에 handleEvent를 정의하고, 이후 Scroll Area에 Event Listener를 추가할 때

iScroll instance를 2번째 인자로 전달한다.

Spider Monkey Universe [1]

1. What is Spider Monkey?

   Spider Monkey는 JavaScript를 동적으로 처리해주는 JS엔진으로써 Mozilla재단에 의해 Open Source로 개발되었다.

   따라서 누구나 자신의 C/C++ Program에 JavaScript Engine을 embed 할 수 있다.
2. Spider Monkey Universe
   Spider Monkey를 통해 JavaScript를 처리하기 위해서는 반드시 3가지의 구성요소(JSRuntime, JSContext, JSObject)가 
필요하다. 이때 3가지 구성요소의 대략적인 관계는 아래 그림과 괕다.
위의 그림과 같이 일반적인 Application의 경우 하나의 Runtime을 갖는다. 하나의 Runtime에는 다수의 Context가 
존재할 수 있고 Context위에는 Script에서 사용하는 Object나 String등이 존재하게 된다. 
Runtime : 사용자가 사용하는 Object나 Variable, Context등을 관리하기 위해 사용되는 Memory공간이다.
            Code Ex) JS_Runtime *rt = JS_NewRuntime(8 * 1024 * 1024);
                             함수의 인자는 JS_Engine에 요구하는 메모리 양(byte)이다.
                             만약 Runtime이 요구한 메모리를 모두 사용했을 경우 Garbage Collector가 자동으로 호출된다.
                             JS_DestroyRuntime(rt); // runtime을 해제할 때 사용되는 함수
Context : JavaScript Code와 Object와 관련하여 많은 일이 이루어지는 공간이다. 대표적인 작업으로는 Script를 
compile하고, execute 하는 작업과 Object의 property값을 설정하고 얻어오는 작업, JavaScript Data의 Type변환 등이 
이루어지는 공간이다. 
            Code Ex) JS_Context *cx = JS_NewContext(8 * 1024);
                             함수의 인자는 Script가 요구하는 variable이나 object를 모두 처리할 수 있을 만큼 충분히
                             큰 양이어야 한다. Script의 실행이 종료되면 context는 freed되거나 다른 script에게 할당된다.
                             JS_DestroyContext(cx); // context를 해제할 때 모든 정보가 사라지게 된다.
Object : 실제 JavaScript에서 사용하는 Object의 경우 아래의 Code를 통해 생성할 수 있다.
            Code Ex) global = JS_NewObject(cx, &global_class, NULL, NULL);
                             이때 함수의 첫번째 인자인 cx가 Object가 생성되는 context를 나타낸다.
위의 그림과 같이 JS_Engine(Spider Monkey)은 하나의 Runtime위에 다수의 Context를 생성한 뒤 

Context에서 Script를 처리하여 Runtime안에 Object를 생성한다.

[JavaScript] 함수 실행 대기 setTimeout(param1, param2);

JavaScript에서 C나 C++의 delay() 역활을 하는 함수.

setTimeout(param1, param2);

param2는 지연시키고자 하는 시간을 밀리세컨단위로 입력해야 하며

param1에는 param2만큼의 시간이 경과한 뒤에 실행시키고자하는 함수가 위치한다.

setTimeout(“quick_sort(“+ 0 +”, “+ (j-1) +”)”, 2500);

만약 이렇게 사용하고 있다면 param1 = (“quick_sort(“+ 0 +”, “+ (j-1) +”)”

param2 = 2500

즉 2.5초 뒤에 quick_sort라는 함수를 실행시킨다는 의미다. 이때 함수의 인자는 “+ 변수명 +” 이렇게

입력하여야 정상적으로 실행된다.

이때 C나 C++의 delay()와 다른점은 C나 C++의 delay() 함수의 경우 delay() 이후의 작업도

수행되지 않은 상태로 남겨져 있는 반면에 JavaScript의 setTimeout( )함수의 경우는

setTimeout( )함수에 대한 부분에 대해서만 지연이 발생하고 이후의 script는 지속적으로

수행한다.

따라서 만약 Script의 실행 순서가 변경되지 말아야 한다면 setTimeout 함수는 사용을 자제하여야 한다.

© 2017 Regular Motion

Theme by Anders NorenUp ↑