검색결과 리스트
글
자바스크립트 JavaScript
스크립트언어 Scripting language
스크립트 언어는 프로그램과 독립하여 사용되고 일반적으로 응용프로그램의 언어와 다른언어로 사용되어 최종 사용자가 응용프로그램의 동작을 사용자의 요구에 수행할 수 있도록 해준다. 스크립트는 연극 용어에서 유래되었으며 초창기 스크립트 언어는 배치언어 (batch languages) 또는 작업 제어 언어(job control language)라고도 불리었다.
자바스크립트 JavaScript
객체 기반의 스크립트 프로그래밍 언어
웹 사이트에서 많이 사용하며, 다른 응용프로그램의 내장 객체에도 접근할 수 있는 기능을 가지고 있다. 자바스크립트가 썬 마이크로시스템즈의 자바와 구문이 유사한 점도 있지만, 이는 사실 두 언어 모두 C언어의 기본 구문을 바탕으로했기 때문이고, 자바와 자바스크립트는 직접적인 관련성이 없다. 이름과 구문 외에는 자바보다 셀프와 유사성이 많다.
모카(Mocha) -> 라이브스크립트(LiveScript) -> 자바스크립트(JavaScirpt)
2013년 1월 기준으로 최신 버전은 자바스크립트 1.8.5, 표준 ECMA-262 3판 (edition)에 대응하는 버전은 1.5이다. ECMA스크립트는 쉽게 말해 자바스크립트의 표준화된 버전이다. 자바스크립트는 브라우저마다 지원되는 버전이 다르다.
서버사이드 자바스크립트 CommonJS, AMD등의 모듈화
2005년 Ajax가 활성화되면서 자바스크립트의 연산이 증가했고 자연스럽게 더욱 빠른 자바스크립트 엔진의 필요성이 대두되었다. 이런 맥락에서 2008년 구글이 공개한 V8 엔진은 많은 주목을 받았는데 기존 자바스크립트 엔진보다 월등히 빨랐을 뿐만 아니라, 브라우저 밖에서도 충분히 쓸만한 성능을 자랑했다.
V8 엔진의 등장은 서버사이드 자바스크립트 진영에 활기를 불어넣게 되었는데 자바스크립트는 모듈화를 언어 자체에서 지원하지 않았다. 때문에 모듈화에 필요한 여러 요소들이 존재하지 않기에 별도의 표준이 필요했고 그 결과 탄생된 표준 이 CommonJS, AMD이다. 이들의 목표는 자바스크립트의 표준 라이브러리를 만드는 것이었다.
https://github.com/amdjs/amdjs-api/wiki/AMD
주요 쟁점
- 서로 호환되는 표준 라이브러리가 없다.
- 데이터베이스에 연결할 수 있는 표준 인터페이스가 없다.
- 다른 모듈을 삽입하는 표준적인 방법이 없다.
- 코드를 패키징해서 배포하고 설치하는 방법이 필요하다.
- 의존성 문제까지 해결하는 공통 패키지 모듈 저장소가 필요하다.
모듈화는 세 부분으로 이루어진다.
- 스코프 (Scope) : 모든 모듈은 자신만의 독립적인 실행 영역이 있어야 한다.
- 정의 (Definition) : 모듈 정의는 exports 객체를 이용한다.
- 사용 (Usage) : 모듈 사용은 require 함수를 이용한다.
fileA.js
var a = 3;
b=4;
exports.sum = function(c, d) {
return a + b + c + d;
}
fileB.js
var a = 5;
b = 6;
var moduleA = require("fileA");
moduleA.sum(a,b); // 3+4+5+6 = 18
예에서 CommonJS 모듈의 명세는 모든 파일이 로컬 디스크에 있어 필요할 때 바로 불러올 수 있는 상황을 전제로 한다. 하지만 이런 방식은 브라우저에서는 결정적인 단점이 있다. 필요한 모듈을 모두 받을 때까지 아무것도 할 수 없기 때문이다. 해결법은 동적으로 <script> 태그를 삽입하는 방법..
비동기 모듈 로드 문제
JavaScript가 브라우저에서 동작할 때는 서버 사이드 JavaScript와 달리 파일 단위의 스코프가 없다. 또한 표준 <script> 태그를 이용해 앞에서 예로 든 fileA와 fileB를 차례대로 로드하면, fileB의 변수가 fileA의 변수를 모두 덮어쓰게 되는 전역변수 문제도 발생한다.
이런 문제를 해결하려고 CommonJS는 서버 모듈을 비동기적으로 클라이언트에 전송할 수 있는 모듈 전송 포맷(module transport format)을 추가로 정의했다. 이 명세에 따라 서버사이드에서 사용하는 모듈을 다음 예의 브라우저에서 사용하는 모듈과 같이 전송 포맷으로 감싸면 서버 모듈을 비동기적으로 로드할 수 있게 된다.
서버사이드에서 사용하는 모듈
// complex-numbers/plus-two.js
var sum = require("./math").sum;
exports.plusTwo = function(a){
return sum(a, 2);
};
브라우저에서 사용하는 모듈
// complex-numbers/plus-two.js
require.define({"complex-numbers/plus-two": function(require, exports){
//콜백 함수 안에 모듈을 정의한다.
var sum = require("./complex-number").sum;
exports.plusTwo = function(a){
return sum(a, 2);
};
},["complex-numbers/math"]);
//먼저 로드되어야 할 모듈을 기술한다.
브라우저에서 사용하는 모듈 부분에서 특히 주목해야 할 것은 require.define() 함수를 통해(함수클로저) 전역 변수를 통제하고 있다는 사실이다.
본래 CommonJS가 JavaScript를 브라우저 밖으로 꺼내기 위한 노력의 일환으로 탄생했기 때문에 브라우저 내에서의 실행에 중점을 두었던 AMD와는 합의를 이끌어 내지 못하고 결국 둘이 분리되었다
두 진영에서 정의하는 모듈 명세의 차이는 모듈 로드에 있다.
필요한 파일이 모두 로컬 디스크에 있어 바로 불러 쓸 수 있는 상황, 즉 서버사이드에서는 CommonJS 명세가 AMD 방식보다 간결하다. 반면 필요한 파일을 네트워크를 통해 내려받아야 하는 브라우저와 같은 환경에서는 AMD가 CommonJS보다 더 유연한 방법을 제공한다.
ConTexts VS Scope
모든 함수의 실행은 스코프, 그리고 스코프와 연결된 컨텍스트를 갖는다. 근본적으로 스코프는 함수 기반이고, 컨텍스트는 객체 기반이다. 다시 설명하면 스코프는 함수가 실행될 때 그리고 각각의 실행에 대해서 그 함수의 접근이 달라지는 것을 말한다. 컨텍스트는 항상 this 키워드의 값이며, 현재 실행되는 코드를 소유하는 객체의 레퍼런스를 가리킨다.
this 컨텍스트란?
컨텍스트는 거의 대부분 함수가 어떻게 실행되느냐에 따라 결정된다. 함수가 객체의 메소드로서 불리게 되면, this는 메소드를 부른 객체로 설정된다.
실행 컨텍스트와 스코프 체인
자바스크립트는 싱글 스레드로 작동하는 언어라서, 브라우져에서 한번에 한가지만 할 수 있다. 자바스크립트 인터프리터가 초기에 코드를 실행할 때는, 기본적으로 글로벌 컨텍스트에서 실행하며 들어간다. 그리고 각 함수가 실행될 때마다 새로운 실행 컨텍스트가 생기게 된다.
"실행 컨텍스트"라는 단어는 실제로 그 의도나 목적들이 스코프에 관련된 것이지 앞에서 이야기한 컨텍스트가 아니여서 혼란이 생긴다. 이런 애매한 명명 규칙은 ECMAScript 스펙에 정의된 단어라서 더 구리다.
새로 실행 컨텍스트가 생길 때마다 스코프체인이라 불리는 곳의 맨 위에 붙게 된다. 브라우져는 항상 스코프체인의 최상위를 실행한다. 한번 완료되면 스택의 맨 위에서 사라지게 되고, 컨트롤은 그 아래의 실행 컨텍스트로 넘어간다. 예제를 보자.
function first(){
second();
function second(){
third();
function third(){
fourth();
function fourth(){
// do something
}
}
}
}
first();
위의 코드가 실행되면 중첩된 함수들을 따라서 fourth 함수까지 따라 내려온다. 이 때 스코프체인은 위에서부터 아래로, fourth, third, second, first, global이 될 것이다. fourth 함수는 전역변수나 first, second, third 및 그 자신의 내부에 있는 어떤 변수들에도 접근할 수 있다. fourth 함수의 실행이 끝나게 되면 스코프체인에서 빠지고 실행은 third에서 계속된다. 이 과정은 모든 코드의 실행이 완료될 때까지 계속된다.
다른 실행 컨텍스트들 사이에서 변수명이 충돌나면 스코프체인을 로컬에서 글로벌로 타고 올라가면서 찾는다. 이는 같은 이름의 변수가 있을 때 스코프 체인에서 로컬 변수가 제일 우선순위가 높다는 뜻이다.
실행 컨텍스트는 생성과 실행 부분으로 나눌 수 있다. 생성 부분에서 인터프리터는 모든 변수들, 함수 선언, 실행 컨텍스트 내부에 정의된 인자들로 이루어진 변수 객체(혹은 활성 객체-activation object-라 불리는)를 만든다. 다음으로는 스코프 체인이 초기화되고, 값이 결정되는건 마지막이다. 그리고 실행 부분에서는 코드를 한줄씩 읽어서 실행한다.
간단히 말해서, 함수의 실행 컨텍스트 내에서 변수에 접근할 때마다 항상 그 실행 컨텍스트의 변수 객체에서 부터 탐색이 시작된다. 변수 객체에서 변수를 찾을 수 없으면 스코프체인에서 탐색이 계속된다. 스코프체인을 따라 올라가면서 변수명이 있는지 모든 실행 컨텍스트의 객체 변수를 확인한다.
자바스크립트 스코프 (Scope)
변수가 스크립트 안의 어느 장소에서 참조할 수 있는가에 대한 개념
자바스크립트 스코프에는 스크립트 전체에서 참조할 수 있는 글로벌 스코프와 정의된 함수 안에서만 참조할 수 있는 로컬 스코프로 분류할 수 있다.
자바의 스코프는 블록 스코프 즉 {} 안에서의 스코프 유지가 가능했지만, 자바스크립트에서는 이를 지원하지 않으니
if ( a > b ) {
var c;
}
같은 구문을 사용할 때 c는 if문이 끝나도 유지된다.
또, 로컬 스코프 사용에 유의해야되는데
var scope = "Global";
function getValue() {
document.writeln(scope);
var scope = 'Local Variable';
return scope;
}
document.writeln(getValue()); //Local variable
document.writeln(scope); // Global
위의 구문에서 함수 가장 첫줄에 보여지는 scope 값이 로컬 변수가 세팅되기 전이라 글로벌 스코프 값인 Global이 출력될 것이라 생각하기 쉽지만, 실제로는 undefined가 출력된다.
이는 로컬 변수가 함수가 실행되는 시점에서 이미 유효하기 때문이다.
다만 아직 초기화가 이루어지지 않았기 때문에 undefined가 출력된다.
자바스크립트 클로져 (Closure)
클로져는 그 함수의 지역 변수가 아닌 것들을 위한 참조 환경을 함께 가지고 있는 함수(실행코드)이다.
자바스크립트의 모든 함수는 그 함수의 지역 변수가 아닌 것들을 위한 참조 환경을 함께 가진다.
클로져의 가장 핵심적인 개념은 어휘적인 유효 범위이다. 함수가 실행될 때는 함수가 실행되는 위치가 아닌, 함수가 정의 될 당시의 유효범위에서 실행된다. 브라우져의 가비지 컬렉터는 보통 함수의 로컬 변수의 경우 함수의 실행이 끝나는 시점에 메모리를 해제해버리지만, 클러져의 속성을 유지하기 위해 로컬 변수를 사용하는 함수가 밖으로 내보내질 경우 메모리를 해제하지 않고 해당 값을 유지한다.
클로져는 지역변수의 한계를 극복하여 함수 호출의 경계를 넘어서도록 지역변수를 확장하여 사용하는 기법을 가능하게 한다.
function foo(){
var local = 'private variable';
return function bar(){
return local;
}
}
var getLocalVariable = foo();
getLocalVariable() // private variable
중첩된 함수가 있을 때 그 변수가 정의된 함수의 밖에서 접근하는 형태이며, 리턴된 함수로 외부에서 실행될 수도 있다. 함수 외부에서 로컬 변수들, 인자들, 내부에 선언된 함수에 계속 접근할 수 있다. 캡슐화는 바깥 스코프에서 실행 컨텍스트를 숨기고 보호하며, 공개적인(public) 인터페이스를 드러내서 관리할 수 있다.
클로저의 가장 유명한 타입 중 하나인 모듈 패턴
var Module = (function(){
var privateProperty = 'foo';
function privateMethod(args){
//do something
}
return {
publicProperty: "",
publicMethod: function(args){
//do something
},
privilegedMethod: function(args){
privateMethod(args);
}
}
})();
모듈은 싱글톤처럼 작동하며, 함수의 끝에 있는 열고 닫는 괄호 때문에 컴파일러가 읽자마자 실행된다. 이 클로져의 실행 컨텍스트 외부에서는 접근할 수 있는 멤버들은, 반환된 객체에 있는 메소드들과 속성들이다. (예를 들어, Module.publicMethod) 그러나, 모든 private 속성들과 메소드들은 숨겨진 실행 컨텍스트로 애플리케이션이 끝날 때까지 살아남아 있는데, public Method들을 통해 변수들을 접근 할 수 있다는 뜻이다.
RECENT COMMENT