[JavaScript ] JavaScript 함수 다시보기 정리

Sonny·2020년 2월 5일
1

JavaScript

목록 보기
27/29
post-thumbnail

JavaScript 함수

JavaScript의 함수는 일급 객체이며 private 변수 또는 메소드 뿐만 아니라
함수의 특징을 이용하여 public 속성과 메소드를 제공하며 JavaScript 모듈을 작성하는 좋은 도구이다.

또한 JavaScript의 가장 큰 문제점 중의 하나는 전역 스코프에 정의된 것은 코드 내의 어디서든지 접근 가능하다는 것이다.
이는 즉시실행함수를 통해 해결할 수 있다.

일급 객체란?

아래와 같은 조건을 충족시키는 객체만 일급 객체라 할 수 있다.

  • 일급 객체는 변수에 저장할 수 있어야 한다.
  • 일급 객체는 함수의 파라미터로 전달할 수 있어야 한다.
  • 일급 객체는 함수의 반환값으로 사용할 수 있어야 한다.
  • 일급 객체는 자료 구조에 저장할 수 있어야 한다.

함수의 익명함수

자바스크립트에서 함수를 정의하는 방법은 아래와 같이 크게 두가지로 나뉜다.

함수 선언식

함수선언식으로 정의된 함수는 JavaScript 인터프리터가 스크립트가 로딩되는 시점에 바로 초기화하고
이를 변수 객체에 저장한다. 그렇기 때문에 함수 선언 위치와는 상관없이 소스 내 어느 곳에서든 호출이 가능하다.

// 함수선언식(function declaration)
function company() {  
    /* 실행코드 */
}

함수 표현식

함수표현식으로 정의된 함수는 런타임시에 해석되고 실행이 된다.

// 기명 함수표현식(named function expression) 
var company = function company() {  
    /* 실행코드 */
}; 

// 익명 함수표현식(anonymous function expression)
var company = function() {  
    /* 실행코드 */
};

// 기명 즉시실행함수(named immediately-invoked function expression)
(function company() {
    /* 실행코드 */
}());

// 익명 즉시실행함수(immediately-invoked function expression)
// Javascript 대가이신 더글라스 클락포트의 권장 표기법
(function() {
    /* 실행코드 */
}());

// 익명 즉시실행함수(immediately-invoked function expression)
(function() {
    /* 실행코드 */
})();

즉시실행함수

외부에 공유되면 안되거나 공유될 필요가 없는 속성, 메소드 또는 다른 스크립트 파일 내에서
동일한 이름으로 명명된 변수나 함수가 있을 경우, 원치 않는 결과를 가져올 수 있는데
이러한 경우를 예방하고자 즉시실행함수를 사용한다.

// 함수표현식에 의한 명시적인 함수호출
var app = function() {  
    console.log('함수 호출'); // "함수 호출" 출력
};
app();	// "함수 호출"

함수표현식은 함수를 정의하고, 변수에 함수를 저장한 뒤 실행하는 일련의 과정을 거친다.

// 즉시실행함수
(function() {
    console.log('함수 호출'); // "함수 호출" 출력
}());	// "함수 호출"

즉시실행함수는 위와 같은 과정을 거치지 않고 즉시 실행되지만 위 두개의 코드는 동일한 동작을 한다.

var app = (function() {  
    var privateVar = 'private';
    return {
        prop : privateVar
    };
}());
console.log(app.prop);	// "private" 

위 코드는 변수를 선언하고 이 변수에 즉시실행함수를 할당한 것이다.

변수의 접근 범위가 함수 내부가 아닌 외부에서도 가능해진 것을 알 수 있다.
이와 같이, 즉시 실행함수는 변수의 스코프를 포함하는 데 사용되며 외부에서 함수 내의 변수 접근을 통제할 수 있다.

(function($) {
    // 함수 스코프 내에서 $는 jQuery Object임.
    console.log($);
}(jQuery));

$를 글로벌 변수로 사용하는 라이브러리를 한개가 아닌 여러개를 같이 사용한다면 $ 변수에 충돌이 생긴다.
하지만 위와 같이 파라미터를 전달하는 방법으로 $ 변수에 대한 충돌을 예방할 수 있다.
이처럼 즉시실행함수는 코드 충돌 없이 구현할 수 있어 플러그인이나 라이브러리 등을 만들 때 많이 사용된다.

모듈 패턴

JavaScript는 언어 레벨에서 캡슐화를 위한 접근제어자(private, public 등), 모듈 간의 구분을 위한 패키지가 명시적으로 제공되지 않는다.

즉시실행함수는 작성한 코드 외에 함께 사용하는 외부 라이브러리와도 충돌없이 구동하는 샌드박스를 제공한다.
이 특징과 단위기능별로 작성된 코드를 분리된 개별 파일 형태로 유지한다면 앞서 언급한 모듈화를 위한 조건을 해결할 수 있다.

var clerk = (function() {  
    var name = 'Teo';
    var sex = '남자';
    var position = '수석 엔지니어';
    // salary private
    var salary = 2000;
    var taxSalary = 200;
    var totalBonus = 100;
    var taxBonus = 10;

    var payBonus = function() {
        totalBonus = totalBonus - taxBonus;
        return totalBonus;
    };
    var paySalary = function() {
        return salary - taxSalary;
    };

    // Public 속성, 메소드
    return {
        name : name,
        sex : sex,                 
        position : position,
        paySalary : paySalary,
        payBonus : payBonus
    };
}());

// name 속성은 public
console.log(clerk.name);	// 'Teo' 
// salary 변수는 즉시실행함수 내부 변수이므로 private
console.log(clerk.salary);	// undefined

// paySalary 메소드는 public
console.log(clerk.paySalary());	// 1800

// payBonus 메소드는 public
console.log(clerk.payBonus());	// 90
console.log(clerk.payBonus());	// 80

즉시실행함수를 위와 같이 사용하면 언어 레벨에서 제공하지 못하는 모듈화 지원도구를 극복할 수 있으며
이렇게 작성된 코드를 분리된 파일로 구성하면 재사용성을 높일 수 있다.

JavaScript 모듈 작성 시 코드 순서

  1. 모듈 스코프 내에서 사용할 변수 작성
  2. 유틸리티 메소드 작성
  3. DOM 조작 메소드 작성
  4. 이벤트 핸들러 작성
  5. Public 메소드 작성
// SPA 모듈 작성 순서 예시
var app = (function() {

    // 1. 모듈 스코프 내에서 사용할 변수 작성
    var scopeVar = {};
    var utilMethod;
    var manipulateDom;
    var eventHandle;
    var initModule;

    // 2. 유틸리티 메소드 작성
    utilMethod = function() {
        // 실행코드
    };

    // 3. DOM 조작 메소드 작성
    manipulateDom = function() {
        // 실행코드
    };

    // 4. 이벤트 핸들러 작성
    eventHandle = function() {
        // 실행코드
    };

    // Public 메소드 작성
    initModule = function() {
        // 실행코드
    };

    return {
        init : initModule
    };
}());

라이브러리 모듈화를 위한 코딩기법

아래는 라이브러리 모듈화를 위한 코딩 기법의 예시이며 크게 5가지로 나뉘어져 있다.

Library 모듈화를 위한 코딩기법 1 - call() 이용하기

(function() {
    'use strict';
    var root = this;
    var version = '1.0';
    var Module1;
    if(typeof exports !== 'undefined') {
        Module1 = exports;
    } else {
        Module1 = root.Module1 = {};
    }
    Module1.getVersion = function() {
        return version;
    }
}).call(this);
console.log(Module1.getVersion());

Library 모듈화를 위한 코딩기법 2 - 전역 객체를 인자로 전달하기

(function(global) {
    var root = global;
    var version = '1.0';
    var Module2;
    if(typeof exports !== 'undefined') {
        Module2 = exports;
    } else {
        Module2 = root.Module2 = {};
    }
    Module2.getVersion = function() {
        return version;
    }
}(this));
console.log(Module2.getVersion());

Library 모듈화를 위한 코딩기법 3 - 즉시실행함수 내부에서 전역 객체를 내부 변수에 할당하기

(function() {
    var root = this;
    var version = '1.0';
    var Module3;
    if(typeof exports !== 'undefined') {
        Module3 = exports;
    } else {
        Module3 = root.Module3 = {};
    }
    Module3.getVersion = function() {
        return version;
    }
}());
console.log(Module3.getVersion());

Library 모듈화를 위한 코딩기법 4 - apply() 이용

/**
 * Library 모듈화를 위한 코딩기법 4
 * apply 함수 이용
 */
(function() {
    var root = this;
    var version = '1.0';
    var Module4;
    if(typeof exports !== 'undefined') {
        Module4 = exports;
    } else {
        Module4 = root.Module4 = {};
    }
    Module4.getVersion = function() {
        return version;
    }
}).apply(this) ;
console.log(Module4.getVersion());

Library 모듈화를 위한 코딩기법 5 - 기명 즉시실행함수 이용

var Module5 = (function() {  
    var root = this;
    var version = '1.0';
    var Module;
    if(typeof exports !== 'undefined') {
        Module = exports;
    } else {
        Module = root.Module = {};
    }
    Module.getVersion = function() {
        return version;
    }
    return Module;
}());
console.log(Module5.getVersion());  

위 포스팅은 JavaScript - 함수을 보며 공부하고 정리한 내용입니다.

참고 사이트

profile
FrontEnd Developer

0개의 댓글