ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 함수
    Javascript 2020. 1. 2. 22:19

    생략 가능한 전달인자(Optional Arguments)

    함수 호출 시점에 전달인자를 생략할 수 있게 함수를 작성하는 것이 유용하다. 생략될 수 있는 전달인자는 적당한 기본값을 할당해 줄 수 있어야만 한다.

    1
    2
    3
    4
    5
    6
    function copyPropertyNamesToArray(o, /* optional */ a) {
    if (!a) a= []; // a가 정의되지 않았거나 혹은 null이라면 빈 배열을 사용한다. 
    for(var property in o) 
        a.push(property);
    return a;
    }

     

    가변 길이 전달인자 목록: 전달인자 객체

    arguments는 Arguments 객체를 참조하는 특별한 프로퍼티다. 함수에 전달된 전달인자의 값을 전달인자 이름이 아니라 숫자를 사용해 접근하기 위한 방법을 제공한다. 자바스크립트는 호출 시점에서는 고정된 개수의 전달인자와는 상관없이 임의 개수의 전달인자들을 건네받을 수 있다. Arguments 객체는 이름이 붙어있든 없든 상관없이 건네받은 모든 전달인자의 값에 접근하기 위한 방법을 제공한다. 

    1
    2
    3
    4
    5
    6
    7
    function f(x, y, z) {
        // 먼저 올바른 개수의 전달인지를 받았는지 검사한다. 
        if (arguments.length != 3) {
        throw new Error("function f called with" + arguments.length + "arguments , but i t expects 3 arguments.");
        }
        // 이제 함수의 작업을 시작한다.
    }

     

    메서드로서의 함수

    메서드는 객체 프로퍼티에 저장되어 객체를 통해 호출할 수 있는 자바스크립트 함수이다. 

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var calculator = { // 객체 리터럴 
        operand1: 1,
        operand2: 1,
        compute: function() {
            this.result = this.operand1 + this.operand2;
        }
    };
    calculator.compute(); // 1+1은 무엇일까요?
    print(calculator.result);

    여기서 this 키워드는 중요하다. 메서드로 사용되는 함수는 그 메서드가 속해 있는 객체를 암묵적 전달인자로 건네받는다. 대체로 메서드는 그 메서드가 속해 있는 객체에 대해서 무엇인가 연산을 수행하기 때문에, 메서드 형태로 함수를 호출하는 구문은 그 함수가 객체와 관련해 작동한다는 사실을 표현하는 세련된 방법이라고 할 수 있다.

    만약 함수를 메서드로서가 아닌 함수로 호출했다면 this 키워드는 전역 객체를 가리킨다. this는 키워드임을 주의하자.

     

    apply(), call() 메서드

    이 메서드를 사용하면 함수가 마치 다른 어떤 객체의 메서드인 것처럼 호출할 수 있다. call()과 apply() 메서드의 첫 번째 전달인자는 함수가 소속되어 호출될 객체를 지정하며 이 전달인자는 함수 몸체 안에서 this 키워드의 값이 된다.

    call() 메서드의 나머지 전달인자들은 함수가 호출될 때 함수의 전달인자로 건네진다.

    1
    f.call(o, 12);

    f()에 두 숫자를 전달하고 이 함수를 마치 객체 0의 메서드인 것처럼 호출하는 방식이다.

    이 표현은 아래와 유사하다.

    1
    2
    3
    o.m = f;
    o.m(1,2);
    delete o.m;

     apply()는 call()과 유사하지만 함수로 건네줄 전달인자들을 배열로 지정하는 차이점이 존재한다.

    1
    f.apply(o, [1,2]);

     

    지역 변수 (함수 수준 범위)

    자바스크립트는 블럭-수준(block-level)의 범위를 가지고 있지 않다. 대신, 자바스크립트는 함수-수준(function-level)의 범위를 가진다. 함수 내에 정의된 변수는 지역 범위를 가지며, 해당 함수와 내부 함수에서만 접근이 가능하다. 

    1
    2
    3
    4
    5
    6
    var name = "Richard";
    function showName() {
         var name = "Jack"// 지역 변수; showName()함수에서만 접근가능.
         console.log(name); // Jack
    }
    console.log(name); // Richard : 전역 변수

    그러므로, 항상 지역변수를 사용하기 이전에 선언하도록 해야한다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    // 지역변수를 var키워드로 선언하지 않았을 경우, 그것은 전역-범위(global-scope)가 됩니다.
    var name = "Michael Jackson";
    function showCelebrityName() {
         console.log(name);
    }
    function showOrdinaryPersonName() {
         name = "Johnny Evers";
         console.log(name);
    }
    showCelebrityName(); // Michael Jackson
    // name 은 지역변수가 아닙니다. 이것은 전역변수 name을 변경해 버립니다.
    showOrdinaryPersonName(); // Johnny Evers
    // 이제 전역변수 name은 Johny Evers입니다. 더이상, 셀럽의 이름은 없습니다. -.-;;
    showCelebrityName(); // Johnny Evers
    // 해결책은 지역변수 선언시 var 키워드를 사용하는 것입니다.
    function showOrdinaryPersonName() {
         var name = "Johnny Evers"// 이제 name은 항상 지역변수이며, 전역변수를 덮어쓰지 않습니다.
         console.log(name);
    }

     

    클로저

    외부함수의 변수에 접근할 수 있는 내부 함수를 일컫으며, scope chain으로 표현되기도 한다. 클로저는 클로저 자신에 대한 접근, 외부 함수의 변수에 대한 접근, 전역 변수에 대한 접근, 이렇게 3가지로 구분할 수 있다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function showName(firstName, lastName) {
        var nameIntro = "Your name is ";
        // 이 내부 함수는 외부함수의 변수뿐만 아니라 파라미터 까지 사용할 수 있습니다.
        function makeFullName() {
            return nameIntro + firstName + " " + lastName;
        }
        return makeFullName();
    }
    showName("Michael""Jackson"); // Your name is Michael Jackson

    위와 같이, 내부 함수는 외부 함수의 변수와 파라미터에도 접근할 수 있으나 외부 함수의 arguments 객체를 호출할 수는 없다. 클로저는 외부함수가 리턴된 후에도 외부함수의 변수에 접근할 수 있다. 클로저는 외부 함수의 변수에 대한 참조를 저장하기 때문에 실제 값을 저장하는 것은 아니다. 

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    function celebrityID() {
        var celebrityID = 999;
        // 우리는 몇개의 내부 함수를 가진 객체를 리턴할것입니다.
        // 모든 내부함수는 외부변수에 접근할 수 있습니다.
        return {
            getID: function() {
                // 이 내부함수는 갱신된 celebrityID변수를 리턴합니다.
                // 이것은 changeThdID함수가 값을 변경한 이후에도 celebrityID의 현재값을 리턴합니다.
                return celebrityID;
            },
            setID: function(theNewID) {
                // 이 내부함수는 외부함수의 값을 언제든지 변경할 것입니다.
                celebrityID = theNewID;
            }
        }
    }
    var mjID = celebrityID(); // 이 시점에, celebrityID외부 함수가 리턴됩니다.
    mjID.getID(); // 999
    mjID.setID(567); // 외부함수의 변수를 변경합니다.
    mjID.getID(); // 567; 변경된 celebrityID변수를 리턴합니다.

    위의 코드를 보면 외부 함수의 메서드를 이용해서 값을 변경할 경우, 원래의 값에서 변경된 것을 볼 수 있다. 이렇게 외부 함수에 값 변화에 즉각적으로 반응한다는 것은 참조 값을 사용한다는 것을 의미한다.

     

    출처

    자바_스크립트_완벽가이드

     

    http://chanlee.github.io/2013/12/10/javascript-variable-scope-and-hoisting/ 

     

    자바스크립트의 변수범위와 호이스팅

    이 글에서, 우리는 자바스크립트 변수의 범위(scope)와 호이스팅(hoisting), 그리고 이 두가지의 특징에 관해 배워보겠습니다. 자바스크립트의 변수범위와 호이스팅이 작동하는 원리를 이해하는것은 필수적입니다. 이 두가지 컨셉은 직관적이면서도 이해하기가 쉽지 않습니다. 거기에는 미묘한 차이가 있으며, 자바스크립트 프로젝트에서 성공하기 위해서는 반드시

    chanlee.github.io

     

    'Javascript' 카테고리의 다른 글

    Client-side Javascript 1  (0) 2020.01.03
    클래스  (0) 2020.01.03
    객체와 배열  (0) 2020.01.02
    문장  (0) 2020.01.02
    변수  (0) 2020.01.02
Designed by Tistory.