본문으로 바로가기

jQeury 의 래퍼 객체의 실체

category Web Tech/jQuery 2015. 6. 20. 13:47

jQuery 래퍼(wrapper)객체 : $()


$() == jQuery() 의 $, jQuery 는 생성자 함수(클래스)입니다. 


우리가 흔히 쓰는 $() 은 함수를 호출하는 것이고 팩토리(공장) 함수입니다.

$() 는 내부적으로 new jQuery()  를 init 하여 공장처럼 찍어내는 것입니다. 


예를 들어 $() 에 인자값으로 DOM Object 를 넣으면 제이쿼리 객체로 반환해 주는 것입니다. 

실제로 너무 당연하다고 쓰고 있기 때문에 $() 이 함수를 호출한다고 생각 못하는 사용자들도 있을 것입니다. 


$() 팩토리 함수는 생성자(클래스)이기 때문에 주의해서 사용해야할 필요성이 있습니다.


다음과 같은 코드가 있다고 가정해 봅니다.

javascript
$('p').css('border' , '1px solid red');
$('p > a').css('text-decoration' , 'underline');

위의 코드는 팩토리 함수를 잘못 사용한 예입니다. 

제이쿼리가 DOM 을 조작,탐색하는데는 슈퍼맨이지만 슈퍼맨도 크립토나이트라는 약점을 가지고 있습니다. 

제이쿼리도 마찬가지입니다.

위의 코드는 p 태그를 두번 팩토리 함수에 넣어서 두번씩이나 탐색하게 하고 있습니다.



다음의 코드는 p 태그를 한번만 참조(캐시)시키고 있습니다.

javascript
var $p = $('p');

$p.css('border', '1px solid red').children('a').css('text-decoration', 'underline');

$() 팩토리 함수는 붕어빵 틀과 같습니다.  붕어빵 틀인 $() 안에 인자를 넣으면 짠 하고 무언가 제이쿼리 객체가 나오지만 팩토리 함수이기 때문에 계속 같은 것을 던지지 말고 한번만 던져서 캐시, 즉 참조해 놓아야만 같은 것을 또 만들어 내지 않게 되겠죠. 같은 것을 계속 만들게 되면 이는 성능저하의 원인이 됩니다. 

요즘 브라우저의 성능이 좋아져서 체감을 못 할 지도 모르지만 제이쿼리 내부적으로는 엄청나게 많은 일을 반복시키는 결과를 낳습니다.

붕어빵 틀에서 붕어빵을 계속 찍어서 먹다보면 배가 부르겠죠?! 그러면 브라우저도 배가 부르겠죠?!

그렇기 때문에 코딩시에는 항상 참조해놓는 습관을 길러야 하겠습니다.


좀 더 본론으로 들어가 보겠습니다.

제이쿼리 코드를 까 보신 분들은 아시겠지만 제이쿼리의 팩토리 함수는 new jQuery() 입니다.

클래스 단위의 코딩 문법(생성자 함수)으로 설계된 것입니다.

$() 는 new jQuery() 를 리턴하면서 인스턴스가 생성되게 됩니다. 


클래스 단위의 코딩을 살펴 보겠습니다.

javascript
var Coffee = function (name) {
    this.name = name;
    this.drink = function () {
        return this.name + '마신다.';
    }
};

var latte = new Coffee();
var espresso = new Coffee();

console.log(latte.name);
console.log(espresso.name);

latte.drink();
espresso.drink();


위의 코드와 같이 제이쿼리는 내부적으로 new jQuery() 를 하여 인스턴스(객체)를 만들고 있습니다.

이런 제이쿼리의 인스턴스 메서드는 사용자로 하여금 편리한 기능을 제공하고 있지만 잘 못 사용하면 성능저하로 귀결됩니다.

그렇기 때문에 제이쿼리팀에서는 유틸리티 메서드와 인스턴스 메서드가 함께 제공되고 있습니다.

예를 들어 $.each()  는 유틸리티 메서드인 네이티브 메서드라고 하며 $().each()  는 인스턴스 메서드라고 합니다.

이런 점에서 네이티브에 접근하여 사용하는 방법이 빠를 수 밖에 없습니다. 

그렇기 때문에 성능을 고려한다면 인스턴스 메서드, 팩토리 함수는 최소한으로 사용하여야만 합니다.


물론 제이쿼리 팀은 코드의 대부분이 클래스 단위의 프로토타이핑 방식으로 코딩되어 있습니다.

프로토타입은 잠시 접어두고 위의 코드를 다시 짚어보면 한가지 의문점이 생길 수 있습니다. 우리가 사용하는 $() 가 new jQuery() 라고 하는데 실제 사용자들은 $() 만 해도 왜 new jQuery() 가 되는 것일까?! 하고 말입니다.


javascript
function Nav(el) {
    return new Navi(el);
}

function Navi(el) {
    console.log(el)
}

var n = Navi('ss')
console.log(n);

위의 코드를 보고 눈치채신 분들도 계시겠지만 제이쿼리 코드는 위와 같은 방식으로 new 생성자함수() 를 반환하고 있습니다.


다음 아래와 같이 같습니다.

javascript
function $(el) {
    return new jQuery(el);

}

$();

물론 코드 내부적으로 사용자가 인자 값으로 무엇인가 던지면 많은 일들을 거쳐서 우리에게 제이쿼리 객체를 반환하겠지만 실제적으로 사용하는 $() 는 위와 같은 방식으로 리턴이 이루어집니다.



Jaehee's WebClub