jQuery 소스코드 분석과 함께하는 자바스크립트 공부 – 1

이 글은 Decoding jQuery series 를 보고 공부한 점을 정리한 글입니다. 원문의 내용과 똑같은 부분도 있고 제가 알고 있는 내용을 따로 덧붙인 부분도 있으니 원문 – Decoding jQuery – OOP and jQuery part 1 을 꼭 보시기 바랍니다.

——————————————————————————————————————–

jQuery의 core에는 다섯 개의 중요한 개념이 있습니다. 변수(variables, 데이터), 함수(functions), 객체(objects), 프로토타입(prototype), 상속(inheritance)입니다.

jQuery는 jQuery라는 변수에 저장되어 있습니다. jQuery 변수는 두 가지가 있는데 하나는 전역변수(global), 나머지 하나는 지역변수(local)입니다.

자바스크립트의 변수의 유효범위는 함수입니다. 즉, 어떤 변수가 함수안에서 선언되었느냐 밖에서 선언되었느냐에 따라 전역변수인지, 지역변수인지가 결정이 됩니다. 전역변수는 소스코드의 어느 곳에서도 접근이 가능한 변수이고 지역변수는 그 변수에 접근 가능한 범위가 정해져 있는 변수입니다. 그 범위는 바로 그 변수가 선언된 함수의 안쪽이 됩니다.

어떤 함수의 바깥에서는 그 함수의 안쪽에서 선언된 변수에는 접근할 수가 없습니다. 그래서 함수 내부의 지역변수는 외부에서 변수 값을 수정하려는 시도로부터 보호됩니다.

var testVar;    // 전역변수를 만듭니다.

function test() {
    var testVar = 'local test variable';    // 함수 안에서 변수를 하나 만듭니다.
                                            // var 키워드를 사용해서 변수를 새로 만들었으므로 지역변수입니다.
                                            // var 키워드를 사용하지 않았다면 전역변수의 값을 변경하였을 것입니다.
    alert(testVar);
}

test();    // 'local test variable'
testVar = 'global test variable';    // 함수 바깥에서 testVar의 값을 설정합니다. 이때 testVar는 전역변수입니다.
test();    // 'local test variable'

alert(testVar);    // 'global test variable'

전역변수 testVar와 지역변수 testVar는 다르기 때문에 함수 바깥에서 testVar에 새로운 값을 할당해도 함수안쪽의 testVar의 값은 변경되지 않습니다. 반대로 test 함수 안에서 지역변수 testVar의 값을 설정해도 전역변수 testVar에는 영향을 미치지 않기 때문에
alert(testVar); 의 결과는 ‘global test variable’ 입니다. 이와같이 전역변수와 지역변수는 변수의 유효범위가 다르기 때문에 같은 변수명을 가지고 있어도 서로 충돌하지 않습니다.

jQuery의 소스코드를 보면 아래와 같이 jQuery라는 동일한 이름으로 전역변수도 있고 지역변수도 있는 것을 보실 수 있습니다.

// global jQuery
var jQuery = (function() {
  // local jQuery
  var jQuery = function( selector, context ) {
    // ...
  }
})();

..

1. 변수는 데이터를 저장하는데 사용되고 함수는 데이터입니다.
지역변수 jQuery는 아래와 같은 형태로 되어 있습니다.

// local jQuery
var jQuery = function( selector, context ) {
	//...
}

자바스크립트에서 함수는 실제로 데이터입니다. 함수는 데이터이고 데이터는 변수에 담아서 저장할 수 있습니다. 그래서 아래의 두가지 예는 같습니다. 함수에 이름이 있다는 것은(function 키워드 다음에 나오는 jQuery라는 함수명) 함수가 그 이름의 변수에 할당되어 있다는 것과 같은 의미입니다.

// local jQuery
function jQuery( selector, context ){
	//...
}

// local jQuery
var jQuery = function( selector, context ){
	//...
}

..

2. 함수는 이름없이 만들어질 수 있습니다. 이런 함수를 익명함수(anonymous function)라고 합니다.
위에 나온 전역변수 jQuery는 아래와 같은 형태로 되어 있습니다.

// global jQuery
var jQuery = (function() {
	//...
})();

위 코드의 안쪽에 이런 형태로 생긴 익명함수가 있는 것을 보실 수 있습니다.

function() {
	//...
}

자바스크립트에서 데이터는 어떤 변수에 할당되지 않은 상태로 존재할 수 있습니다. 함수는 데이터이기 때문에 마찬가지로 어떤 변수에 할당되지 않은 상태로 있을 수 있고 그래서 함수명이 없는 상태로 존재할 수 있습니다. 물론, 에러도 발생하지 않습니다. 이러한 익명함수는 이름이 없기 때문에(변수에 할당되지 않았기 때문에) 나중에 코드의 다른 곳에서는 불러서 사용할 수가 없습니다. 대신 생성된 즉시 바로 호출해서 사용하는 것은 가능합니다. 아래와 같이 말입니다.

..

3. 익명함수는 스스로 실행될 수 있습니다.(self-invoking, self-executing)
익명함수는 스스로 실행될 수 있습니다. 아래의 코드와 같이 만들어지는 즉시 호출하는 형태로 작성하면 됩니다.

var jQuery = (function() {
	console.log("I am self-invoking.");
})();

위 코드는 (function () { … })() 이런 형태로 되어 있습니다. 왼쪽에 있는 괄호안에 익명함수가 들어있는데 그 것을 괄호로 싼다음 () 로 함수를 실행하고 있습니다. 함수에 이름이 있었다면 함수명 다음에() 를 붙여서 실행했겠지만 이름이 없으므로 함수의 몸체 다음에 바로 () 를 붙여서 실행하는 형태입니다.

이러한 “익명함수 즉시실행 패턴”은 여러가지 이유로 유용하게 사용될 수 있습니다. 그 중 오늘 배운 것과 관련된 것을 말씀드리면 바로 변수의 유효범위를 만들 수 있다는 것입니다. 자바스크립트에서 변수의 유효범위는 함수입니다. 즉 어떤 함수안에서 생성된 변수는 같은 이름을 가진 함수외부의 변수와는 이름만 같을 뿐 다른 변수이므로 서로 충돌이 일어나지 않습니다. 그래서 함수 바깥에 어떤 전역변수들이 있는가에 상관없이 자유롭게 변수명을 지어서 사용할 수 있습니다.

다음글에서는 프로토타입(prototype)과 객체(object)에 대해서 알아봅니다.