Javascript Function

한 번 정의하면 몇번이든 실행할 수 있고 호출할 수있는 자바스크립트 코드 블럭

        function printprops(o) {
            for(var p in o) {
                console.log(p + " : " + o[p] + "\n");
            }
        }
        var arr = [1,2,3,4,5];
        printprops(arr);

Output :

함수 이름은 옵션

함수 정의 표현식에서 함수 이름은 옵션이다.
한 번 사용되고 마는 함수에서 특히 유용.

        var ten = (function(x) {return 10});
        console.log(ten);
        console.log(ten(100));

Output :

함수 선언문은 hoisted 된다.

어디에 함수 선언문이 있든 맨 위로 끌어올려(hoisted) 진다.
하지만 표현식으로 정의된 함수는 변수에 할당되기 전 까지는 참조할 수 없다.

리턴 값이 없는 함수를 procedure라고도 함.

중첩 함수

        function hypotenuse(a, b) {
            function square(x) {return x * x};
            return Math.sqrt(square(a). square(b));
        }

문장으로 선언되는 함수는

함수 내에 함수 중첩가능
but 반복문 내부, 조건문, try / catch / finally 또는 with문 안에 들어갈 수 없다.

표현식은

코드 어디든 위치 가능

함수 호출

  1. 일반적인 함수형태
  2. 메서드 형태
  3. 생성자
  4. call() 과 apply() 메서드를 통한 간접 호출

일반적인 함수 형태

호출 표현식

  • 함수 객체로 평가되는 함수 표현식
  • 여는 괄호
  • 콤마로 구분된 0개 이상의 전달인자 표현식
  • 닫는 괄호

함수 내의 this

  • 일반적인 함수 형태로 사용하려 했으면 this 쓰지 않음
  • strict mode 가 적용되었는지 판단 여부를 위해 사용 가능
    • 엄격모드 X -> global 객체
    • 엄격모드 O -> undefined
var strict = (function() {return !this;}());

메서드 호출

대부분 . 을 사용
[] 도 사용가능

        var calculator = {
            operand1: 1,
            operand2: 1,
            add: function() {
                this.result = this.operand1 + this.operand2;
            }
        }
        calculator.add();
        console.log(calculator.result);
        calculator["add"]();
        console.log(calculator.result);

Output :

메서드 사용 -> 해당 객체에 무언가를 한다는 사실을 나타내는 세련된 방법.

+a : this 키워드의 scope

        var o = {
            m: function() {
                var self = this;
                console.log(this === o); // true
                f();
                function f() {
                    console.log(this === o); // false
                    console.log(self === o);
                }
            }
        }
        o["m"]();

Output :

생성자 호출

new keyword -> 생성자 호출

인자가 없으면 두 문장은 완전히 같은 것.

        var o = new Object();
        var o = new Object;

생성자 함수는 보통 return 사용하지 않음.
함수의 마지막에서 객체를 반환, 혹은 return만 명시 되어있으면 거기서 객체 반환
기본 자료형 값(primitive value)을 반환하면 무시되고 새로생성된 객체가 호출 표현식 값.

간접 호출

call() -> 자신에게 주어진 전달인자를 호출할 함수의 전달인자로 사용
apply() -> 값 배열을 전달인자로 사용.

두 메서드 모두 호출 때 this 값을 명시적으로 지정 가능. -> 어떤 함수든지 특정 객체의 메서드로 호출할 수 있다는 의미

함수 전달인자와 매개변수

Javascript는 함수 매개변수타입, 전달인자 개수, 전달하는 인자의 타입 모두 검사하지 않음.
이를 프로그래머가 관리하는 방법들.

생략 가능한 매개변수

본래 정의된 것 보다 적으면 -> 나머지는 undefined
이렇게 두지 말고 생략된 매개변수에는 기본값을 주는 코드를 쓰자.

        function getPropertyNames(o, /*optional*/ a) {
            if(a == undefined) a = [];
            //or a = a || []
            // || -> 첫번째가 true나 true로 반환되는 값이면 그 값 return, 그렇지 않으면 뒤에 것 return
            for(var property in o) {
                a.push(property);
            }
            return a;
        }

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

본래 정의된 것 보다 많을 때.

        function f(x, y, z) {
            if(arguments.length != 3) {
                throw new Error("인자개수가 3이 아닙니다.")
            }
        }

이렇게 해도 좋지만 javascript의 기본동작인

  • 빠진 인자는 undefined
  • 추가된 인자는 무시
    로도 잘 동작하게 구현 가능.

argument 객체를 직접 수정시

        function g(x) {
            console.log(x);
            arguments[0] = null;
            console.log(x);
        }

엄격모드가 아니면 값 변경, 엄격모드 시 값 변경되지 않음.

callee와 caller 속성

엄격모드에서는 사용 못함.
callee -> 프로퍼티가 현재 실행되고 있는 함수를 참조, 이름없는 함수를 재귀적으로 호출하는데 유용
caller -> 비표준. 이 함수를 호출한 함수를 참조. 호출 스택에 접근할 수 있도록 해줌.

객체의 프로퍼티를 전달인자로 사용하기

easycopy({from : a, to : b, length : 4});

값으로서의 함수

        function square(x) {return x * x};
        var s = square;
        square(4);
        s(4);

        var o = {square: function(x) {return x * x}};
        var y = o.square(16);

        var a = [function(x) {return x*x; }, 20];
        a[0](a[1]);

자신만의 함수 프로퍼티 정의하기

C 에서의 static 지역변수 역할

uniqueInteger.counter = 0;
function uniqueInteger() {
    return uniqueInteger.counter++;
}

함수 이름을 배열처럼 다룸

        function factorial(n) {
            if(isFinite(n) && n>0 && n == Math.round(n)) {
                if(!(n in factorial)) {
                    factorial[n] = n * factorial(n - 1);
                }
                return factorial[n];
            }
            else return NaN;
        }
        factorial[1] = 1;

네임스페이스로서의 함수

javascript 는 단위 block 내에 유효한 변수를 정의하는 방법을 제공하지 않음.
간단한 임시 네임스페이스 처럼 작동하는 함수를 정의하는 기법 사용.

        function mymodule() {
            // 모듈의 지역변수로 사용해서 전역을 어지럽히지 않음
        }
        mymodule(); // 함수 실행 필수

        // 하나의 프로퍼티 선언도 과하다면
        (function() {
            // 모듈 코드가 위치
        }()) // 바로 호출하고 끝냄. function앞 뒤 괄호는 반드시 필요 -> 표현식임을 알림

클로저

함수 객체, 함수의 변수가 해석되는 유효범위(변수 바인딩의 집합) 을 아울러 클로저라고 함
모든 자바스크립트 함수는 클로저.
-> 함수는 객체이고 함수 자신과 관련된 유효범위 체인을 가지고 있기 때문.

클로저는 자신을 정의한 바깥쪽 함수에 바인딩된 지역변수를 포착한다.

        var scope = "global";
        function checkscope() {
            var scope = "local";
            function f() {return scope;};
            return f;
        }
        checkscope()() // local 출력

EX) Counter

내부변수는 private. 오직 count와 reset을 통해서만 제어가능

        function counter() {
            var n = 0;
            return {
                count: function() {return n++;}, 
                reset: function() { n = 0; }
            }
        }

        var c = counter(), d = counter();
        console.log("c : ", c.count());
        console.log("d : ",d.count());
        c.reset()
        console.log("c : ",c.count());
        console.log("d : ",d.count());

Output:

Function 생성자

  • 동적으로 자바스크립트 함수를 생성하고 실행 시간에 컴파일 되는 것을 가능하게 한다.
  • 이걸로 생성하는 함수는 언제나 최상위 레벨 함수로, lexical scoping을 사용하지 않는다.

     

    var f = new function("x", "y", "return x*y);
    // 마지막 인자는 함수의 몸체 텍스트

 

'웹 프로그래밍 > Javascript' 카테고리의 다른 글

Javascript Scope, 변수  (0) 2020.06.23
Javascript Array  (0) 2020.06.23
JavaScript Property  (0) 2020.06.21
JavaScript Object 생성  (0) 2020.06.19
Javascript 세미콜론  (0) 2020.05.30

+ Recent posts