얼마 전 그룹에 올라온 글을 보고...




얼마 전 활동 중인 그룹(undefinedD)에 새롭게 올라온 글을 본 후 JS 생성 패턴에 대해 나름 다시한번 정리해 보는 시간을 가졌다.





먼저 아래는 그룹에 올라온 글에 대한 전문이다.








1. JQuery 객체 생성 패턴



- 아래는 실제 JQuery 코드 상에서 사용되고 있는 객체 생성 패턴의 예이다. 하지만 이와 같은 생성 패턴은 JS Prototype 순환 참조로 인해 포함되지 않아야 할 메서드($.init(name))가 포함되는 문제가 존재한다.



var $ = (function(){


    var $ = function(name){

        return new $.fn.init(name);
    }


    $.fn = $.prototype = {

        init: function(name){
            
            name = name || '';

            this.name = name;

            return this;
        },
        getName: function(){
            return this.name;
        }

    }

    $.fn.init.prototype = $.prototype;

    return $;

}());


console.log('A: ' + $('mohwa').init); // init function
console.log('A: ' + $('mohwa').getName()); // mohwa






2. 수정된 객체 생성 패턴 


- 아래 생성 패턴은 위 JQuery 생성 패턴문제($.init(name) 메서드가 포함되는) 해결하였다.


var $ = (function(){


    var $ = function(name){

        return new init(name);
    }


    function init(name){

        name = name || '';

        this.name = name;

        return this;
    }

    init.prototype.getName = function(){

        return this.name;
    }



    return $;

}());


console.log('B: ' + $('mohwa') === $('mohwa')); // false
console.log('B: ' + $('mohwa').init); // undefined(이전 패턴과 달리 $.init(name) 메서드가 존재하지 않는다.)
console.log('B: ' + $('mohwa').getName()); // mohwa





3. 생성자 + 싱글톤 패턴


- 위 생성자 패턴에 싱글톤 패턴을 추가 하였다.



var $ = (function(){

    // 싱글톤을 위한 인스턴스 private 변수

    var instance = null;

    var $ = function(name){

        return new init(name);
    }


    function init(name){

        name = name || '';

        this.name = name;

        // 싱글톤 패턴
        return instance = instance ? instance : this;
    }

    init.prototype.getName = function(){

        return this.name;
    }



    return $;

}());


console.log('C: ' + $('mohwa') === $('mohwa')); // true
console.log('C: ' + $('mohwa').getName());





4. 객체 생성자(Class)를 강제 시킨다.


instanceof 연산자를 통해 객체 생성자 함수($(name))를 강제 시키는 코드를 추가시킨 패턴이다.




var $ = function(name){

    name = name || '';

    var _this;
    if (!(this instanceof $)) _this = new $(name);
    else _this = this;

    _this.name = name;

    return _this;

};

var $$ = function(){

}

console.log('D: ' + $.call(new $$(), 'mohwa').name); // fn.call(context, arguments) 메서드를 사용해 호출한다.
console.log('D: ' + new $('mohwa').name);